Réécriture d’URL pour ASP.NET Web Forms

par Ruslan Yakushev

Quand vous utilisez le module de réécriture d’URL IIS avec des applications ASP.NET, vous devez vérifier le comportement de votre application web avec les URL réécrites. Cet article décrit les scénarios dans lesquels la réécriture d’URL peut affecter les applications web ASP.NET, et les solutions aux problèmes potentiels.

Sommaire

Définition de l’URL de publication (postback) pour l’élément de formulaire

ASP.NET Web Forms utilise largement les publications (postbacks), ce qui rend la réécriture d’URL un peu difficile pour les pages ASP.NET. Si la page contient un ou plusieurs contrôles serveur web, quand ASP.NET affiche la page, il définit l’attribut d’action de l’élément de formulaire HTML pour qu’il pointe vers la page où se trouve l’élément de formulaire, c’est-à-dire pour qu’il pointe vers lui-même. Si la réécriture d’URL est utilisée pour cette page, l’attribut d’action pointe vers l’URL réécrite, et non vers l’URL demandée par le navigateur. Le navigateur affiche alors l’URL réécrite dans la zone d’adresse chaque fois qu’une publication (postback) se produit.

Pour empêcher l’attribut d’action de pointer vers la mauvaise URL, vous pouvez définir la propriété Action de l’instance HtmlForm de la page sur l’URL de publication (postback) demandée par le navigateur. Vous pouvez obtenir cette URL avec la propriété HttpRequest.RawUrl. L’exemple suivant montre comment modifier la page ASP.NET pour définir l’URL d’action.

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

Remarque

La propriété HtmlForm.Action est disponible à partir de .NET Framework version 3.5 SP1.

Si vous utilisez des pages maîtres ASP.NET, vous pouvez ajouter du code à la méthode Page_Load de la page maître pour définir l’URL d’action de publication (postback) pour toutes les pages qui utilisent cette page maître.

Réécriture d’URL pour le contrôle AJAX UpdatePanel

Quand vous utilisez le module de réécriture d’URL pour réécrire l’URL d’une page qui contient un ou plusieurs contrôles UpdatePanel, le contrôle utilise l’URL réécrite pour toutes les actions effectuées par ce contrôle UpdatePanel. Cela peut affecter le fonctionnement des contrôles du contrôle UpdatePanel, en particulier quand la réécriture d’URL change la hiérarchie de répertoires de l’URL demandée. Par exemple, si vous utilisez le module de réécriture d’URL pour réécrire /Products/Hardware en /Products.aspx, le contrôle UpdatePanel utilise l’URL /Products/Hardware/Products.aspx pour toutes les actions dans le contrôle UpdatePanel. Cela entraîne une erreur de script.

Pour éviter cela, définissez la propriété Action de l’instance HtmlForm de la page comme décrit dans Définition de l’URL de publication (postback) de l’élément de formulaire dans la section précédente.

Utilisation de l’opérateur ~ dans les contrôles serveur web

Vous pouvez utiliser l’opérateur ~ dans les contrôles serveur web ASP.NET pour référencer la racine du répertoire d’application quand vous devez définir un chemin. Toutefois, si la réécriture d’URL change la hiérarchie de répertoires de l’URL demandée, les liens spécifiés avec l’opérateur ~ peuvent être résolus de manière incorrecte. Par exemple, imaginez que la page Default.aspx à la racine d’une application web nommée app1 contient le contrôle Image suivant :

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

Si la réécriture d’URL change l’URL http://localhost/app1/folder/file en http://localhost/app1/default.aspx, les liens spécifiés avec l’opérateur ~ sont résolus par rapport au chemin de l’URL réécrite, qui est relatif au dossier /app1. L’exemple suivant montre le balisage HTML résultant pour l’élément img :

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

Comme le navigateur a demandé http://localhost/app1/folder/file, il essaie d’obtenir l’image à partir de http://localhost/app1/folder/Images/MyImage.gif. Cela entraîne une erreur 404 (Fichier introuvable).

Le module de réécriture d’URL pour IIS comprend une mise à jour pour ASP.NET qui corrige ce comportement. La mise à jour entraîne la résolution de l’opérateur ~ dans les contrôles serveur web par rapport à l’URL demandée à l’origine. Dans l’exemple précédent, le balisage HTML dans la réponse contient alors le chemin d’URL approprié pour l’élément img, comme indiqué dans le balisage suivant :

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

La mise à jour pour ASP.NET s’applique uniquement à .NET Framework 3.5 SP1 et versions ultérieures. Pour obtenir la mise à jour, mettez à niveau .NET Framework vers la version 3.5 SP1, puis exécutez le programme d’installation du module de réécriture d’URL IIS, qui installe la mise à jour ASP.NET.

Réécriture d’URL et contrôles de navigation de site

Un plan de site ASP.NET peut être utilisé pour décrire la structure d’un site web de sorte que l’API de navigation de site et les contrôles de navigation de site puissent exposer une structure de site logique (et non physique). Quand vous utilisez le module de réécriture d’URL avec une application ASP.NET qui utilise la navigation de site, vous voulez généralement que les contrôles de navigation fonctionnent du point de vue de la structure de site logique qui utilise des URL publiques ou virtuelles.

Par exemple, vous pouvez définir un plan de site comme indiqué dans l’exemple suivant :

<?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>

Vous pouvez ensuite définir des règles de réécriture qui effectuent les réécritures suivantes :

  • /Products/ en /Products.aspx
  • /Products/Hardware en /Products.aspx ?category=Hardware
  • /Products/Software en /Products.aspx ?category=Software

La définition d’un plan de site avec ces URL virtuelles peut affecter le fonctionnement de la classe SystemWeb.SiteMap. Quand vous essayez d’accéder à la propriété SiteMap.CurrentNode dans une page ASP.NET, la propriété peut contenir la valeur Null. Cela peut affecter le fonctionnement des contrôles de navigation de site comme SiteMapPath et Menu.

Le module de réécriture d’URL pour IIS comprend une mise à jour pour ASP.NET qui corrige les contrôles de navigation de sorte qu’ils puissent utiliser des URL virtuelles réécrites. Avec cette mise à jour, la propriété SiteMap.CurrentNode référence le SiteMapNode qui correspond à l’URL virtuelle actuellement demandée.

La mise à jour pour ASP.NET s’applique uniquement à .NET Framework 3.5 SP1 et versions ultérieures. Pour obtenir la mise à jour, mettez à niveau .NET Framework vers la version 3.5 SP1, puis exécutez le programme d’installation du module de réécriture d’URL IIS, qui installe la mise à jour ASP.NET.

Empêcher la réécriture des demandes pour les ressources ASP.NET

Les applications web basées sur ASP.NET adressent très souvent des demandes au fichier WebResources.axd pour récupérer les ressources d’assembly et les servir au navigateur web. Ce type de fichier n’existe pas sur le serveur, car ASP.NET génère le contenu dynamiquement quand WebResources.axd est demandé. Par conséquent, si vous avez une règle de réécriture d’URL qui réécrit ou redirige l’URL demandée uniquement si elle ne correspond pas à un fichier ou à un dossier du système de fichiers d’un serveur web, cette règle peut réécrire accidentellement les demandes adressées à WebResources.axd et donc interrompre votre application.

Ce problème peut être facilement évité si vous ajoutez une condition supplémentaire à la règle de réécriture :

<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>