Перезапись URL-адресов для ASP.NET Web Forms
При использовании модуля переопределения URL-адресов IIS с ASP.NET приложениями важно обеспечить правильное поведение веб-приложения с перезаписными URL-адресами. В этой статье описываются сценарии, в которых перезапись URL-адресов может повлиять на ASP.NET веб-приложения и решения потенциальных проблем.
Оглавление
- Задание URL-адреса обратной передачи для элемента Form
- Перезапись URL-адресов для элемента управления AJAX UpdatePanel
- Использование оператора "~" в серверных веб-элементах управления
- Перезапись 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/file
http://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>