Поделиться через


Перезапись URL-адресов для ASP.NET Web Forms

Руслан Якушев

При использовании модуля переопределения URL-адресов IIS с ASP.NET приложениями важно обеспечить правильное поведение веб-приложения с перезаписными URL-адресами. В этой статье описываются сценарии, в которых перезапись URL-адресов может повлиять на ASP.NET веб-приложения и решения потенциальных проблем.

Оглавление

Задание URL-адреса обратной передачи для элемента Form

ASP.NET Web Forms широко использовать обратные передачи, и это несколько усложняет перезапись URL-адресов для ASP.NET страниц. Если страница содержит один или несколько серверных веб-элементов управления, при ASP.NET отрисовывает страницу, она задает атрибут action элемента HTML-формы, указывающий на страницу, на которой находится элемент формы, то есть указывает на себя. Если для этой страницы используется перезапись URL-адресов, атрибут действия указывает на перезаписанный URL-адрес, а не НА URL-адрес, запрошенный в браузере. Это приводит к тому, что браузер будет отображать перезаписанный URL-адрес в поле адреса каждый раз при обратной отправке.

Чтобы атрибут action не указывал на неправильный URL-адрес, можно задать для свойства Action экземпляра HtmlForm на странице URL-адрес обратной передачи, запрошенный браузером. Этот URL-адрес можно получить с помощью свойства HttpRequest.RawUrl. В следующем примере показано, как изменить страницу ASP.NET, чтобы задать URL-адрес действия.

protected void Page_Load(object sender, EventArgs e) 
{ 
    form1.Action = Request.RawUrl; 
}

Примечание

Свойство HtmlForm.Action доступно начиная с платформа .NET Framework версии 3.5 с пакетом обновления 1 (SP1).

При использовании ASP.NET master страниц можно добавить код в метод Page_Load страницы master, чтобы задать URL-адрес действия обратной передачи для всех страниц, использующих эту master страницу.

Перезапись URL-адресов для элемента управления AJAX UpdatePanel

При использовании модуля переопределения URL-адресов для перезаписи URL-адреса страницы, содержащей один или несколько элементов управления UpdatePanel, элемент управления будет использовать перезаписанный URL-адрес для всех действий, выполняемых этим элементом управления UpdatePanel. Это может привести к неправильной работе элементов управления в Элементе управления UpdatePanel, особенно в тех случаях, когда при перезаписи URL-адреса изменяется иерархия каталогов запрошенного URL-адреса. Например, если модуль переопределения URL-адресов используется для перезаписи /Products/Hardware в /Products.aspx, элемент управления UpdatePanel будет использовать URL-адрес /Products/Hardware/Products.aspx для всех действий в элементе управления UpdatePanel. Это приводит к ошибке скрипта.

Чтобы избежать этого, задайте свойство Action экземпляра HtmlForm страницы, как описано в разделе Настройка URL-адреса обратной передачи для элемента Form в предыдущем разделе.

Использование оператора ~ в серверных веб-элементах управления

Оператор ~можно использовать в ASP.NET серверных веб-элементов управления для ссылки на корень каталога приложения, если необходимо задать путь. Однако если перезапись URL-адресов изменяет иерархию каталогов запрошенного URL-адреса, это может привести к неправильному разрешению ссылок, указанных с помощью оператора ~. Например, представьте, что страница Default.aspx в корне веб-приложения с именем app1 содержит следующий элемент управления Image:

<asp:Image runat="server" ImageUrl="~/Images/MyImage.gif" />

Если при перезаписи URL-адреса изменяется с http://localhost/app1/folder/filehttp://localhost/app1/default.aspxна , ссылки, указанные с помощью оператора ~, разрешаются относительно перезаписного URL-пути, который будет находиться относительно папки /app1. В следующем примере показана итоговая разметка HTML для элемента img:

<img src="Images/MyImage.gif" ... >

Так как браузер запросил http://localhost/app1/folder/file, он попытается получить образ из http://localhost/app1/folder/Images/MyImage.gif. Это приводит к ошибке 404 (файл не найден).

Модуль переопределения URL-адресов для IIS содержит обновление для ASP.NET, которое устраняет это поведение. Обновление приводит к разрешению оператора ~ в элементах управления веб-сервера относительно первоначально запрошенного URL-адреса. В предыдущем примере HTML-разметка в ответе будет содержать правильный URL-путь для элемента img, как показано в следующей разметке:

<img src="../Images/MyImage.gif" ... >

Обновление для ASP.NET применяется только к платформа .NET Framework 3.5 с пакетом обновления 1 (SP1) и более поздним версиям. Чтобы получить обновление, обновите платформа .NET Framework до версии 3.5 с пакетом обновления 1 (SP1), а затем запустите установщик модуля переопределения URL-адресов IIS, который установит обновление ASP.NET.

Перезапись URL-адресов и элементов управления навигацией по сайту

ASP.NET карту сайта можно использовать для описания структуры веб-сайта, чтобы API навигации сайта и элементы управления навигацией сайта могли предоставлять логическую (а не физическую) структуру сайта. При использовании модуля переопределения URL-адресов с приложением ASP.NET, использующим навигацию по сайту, обычно требуется, чтобы элементы управления навигацией работали с точки зрения логической структуры сайта, использующего общедоступные или виртуальные URL-адреса.

Например, можно определить карту сайта, как показано в следующем примере:

<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0">
  <siteMapNode url="~/Products/" title="Products" description="Products Home Page">   
    <siteMapNode url="~/Products/Hardware/" title="Hardware" description="Hardware Products" /> 
    <siteMapNode url="~/Products/Software/" title="Software" description="Software Products" />
  </siteMapNode>
</siteMap>

Затем можно определить правила перезаписи, которые выполняют следующие операции перезаписи:

  • /Products/ в /Products.aspx
  • /Products/Hardware to /Products.aspx?category=Hardware
  • /Products/Software to /Products.aspx?category=Software

Определение карты сайта с помощью этих виртуальных URL-адресов может привести к неправильной работе класса SystemWeb.SiteMap. При попытке доступа к свойству SiteMap.CurrentNode на странице ASP.NET свойство может содержать значение NULL. Это может привести к неправильной работе элементов управления навигацией сайта, таких как SiteMapPath и Menu.

Модуль переопределения URL-адресов для IIS включает обновление для ASP.NET, которое исправляет элементы управления навигацией, чтобы они могли работать с перезаписываемыми виртуальными URL-адресами. При этом обновлении свойство SiteMap.CurrentNode будет ссылаться на SiteMapNode, соответствующий запрашиваемому в настоящее время виртуальному URL-адресу.

Обновление для ASP.NET применяется только к платформа .NET Framework 3.5 с пакетом обновления 1 (SP1) и более поздним версиям. Чтобы получить обновление, обновите платформа .NET Framework до версии 3.5 с пакетом обновления 1 (SP1), а затем запустите установщик модуля переопределения URL-адресов IIS, который установит обновление ASP.NET.

Запрет перезаписи запросов для ASP.NET веб-ресурсов

ASP.NET веб-приложения часто выполняют запросы к файлу WebResources.axd для получения ресурсов сборки и их обслуживания в веб-браузере. На сервере нет такого файла, так как ASP.NET динамически создает содержимое при запросе WebResources.axd. Поэтому если у вас есть правило перезаписи URL-адресов, которое выполняет перезапись или перенаправление только в том случае, если запрошенный URL-адрес не соответствует файлу или папке в файловой системе веб-сервера, это правило может случайно перезаписать запросы, сделанные в WebResources.axd, и таким образом нарушить работоспособность приложения.

Эту проблему можно легко предотвратить, добавив одно дополнительное условие в правило перезаписи:

<rule name="RewriteUserFriendlyURL1" stopProcessing="true">
  <match url="^([^/]+)/?$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    <!--  The following condition prevents rule from rewriting requests to .axd files -->
    <add input="{URL}" negate="true" pattern="\.axd$" />
  </conditions>
  <action type="Rewrite" url="article.aspx?p={R:1}" />
</rule>