Riscrittura URL per Web Forms ASP.NET

di Ruslan Kashšev

Quando si usa il modulo IIS URL Rewrite con ASP.NET applicazioni, è importante garantire il comportamento corretto dell'applicazione Web con URL riscritti. Questo articolo illustra gli scenari in cui la riscrittura degli URL può influire sulle applicazioni Web ASP.NET e sulle soluzioni a potenziali problemi.

Sommario

Impostazione dell'URL di postback per l'elemento Form

Web Forms ASP.NET usare ampiamente i postback e ciò rende piuttosto difficile eseguire la riscrittura degli URL per ASP.NET pagine. Se la pagina contiene uno o più controlli server Web, quando ASP.NET esegue il rendering della pagina, imposta l'attributo action dell'elemento modulo HTML in modo che punti alla pagina in cui si trova l'elemento del modulo, ovvero punta a se stesso. Se per tale pagina viene usata la riscrittura dell'URL, l'attributo dell'azione punta all'URL riscritto, non all'URL richiesto dal browser. In questo modo il browser visualizza l'URL riscritto nella casella dell'indirizzo ogni volta che si verifica un postback.

Per impedire che l'attributo azione punti all'URL errato, è possibile impostare la proprietà Action dell'istanza HtmlForm nella pagina sull'URL di postback richiesto dal browser. È possibile ottenere tale URL usando la proprietà HttpRequest.RawUrl. Nell'esempio seguente viene illustrato come modificare la pagina ASP.NET per impostare l'URL dell'azione.

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

Nota

La proprietà HtmlForm.Action è disponibile a partire da .NET Framework versione 3.5 SP1.

Se si utilizza ASP.NET pagine master, è possibile aggiungere codice al metodo Page_Load della pagina master per impostare l'URL dell'azione di postback per tutte le pagine che usano tale pagina master.

Riscrittura degli URL per il controllo UpdatePanel AJAX

Quando si usa il modulo di riscrittura URL per riscrivere l'URL di una pagina contenente uno o più controlli UpdatePanel, il controllo userà l'URL riscritto per tutte le azioni eseguite dal controllo UpdatePanel. Ciò può causare il corretto funzionamento dei controlli nel controllo UpdatePanel, soprattutto nei casi in cui la riscrittura dell'URL modifica la gerarchia di directory dell'URL richiesto. Ad esempio, se si usa il modulo di riscrittura URL per riscrivere /Products/Hardware in /Products.aspx, il controllo UpdatePanel userà l'URL /Products/Hardware/Products.aspx per tutte le azioni all'interno del controllo UpdatePanel. Viene generato un errore di script.

Per evitare che ciò accada, impostare la proprietà Action dell'istanza HtmlForm della pagina come descritto in Impostazione dell'URL di postback per l'elemento Modulo nella sezione precedente.

Utilizzo dell'operatore ~ nei controlli server Web

È possibile utilizzare l'operatore ~ in ASP.NET controlli server Web per fare riferimento alla radice della directory dell'applicazione quando è necessario impostare un percorso. Tuttavia, se la riscrittura dell'URL modifica la gerarchia di directory dell'URL richiesto, questo può causare la risoluzione non corretta dei collegamenti specificati con l'operatore ~ . Si supponga, ad esempio, che la pagina Default.aspx nella radice di un'applicazione Web denominata app1 contenga il controllo Image seguente:

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

Se la riscrittura url modifica l'URL da http://localhost/app1/folder/file a http://localhost/app1/default.aspx, i collegamenti specificati con l'operatore ~ verranno risolti rispetto al percorso URL riscritto, che sarebbe relativo alla cartella /app1. L'esempio seguente mostra il markup HTML risultante per l'elemento img:

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

Poiché il browser ha http://localhost/app1/folder/filerichiesto , tenterà di ottenere l'immagine da http://localhost/app1/folder/Images/MyImage.gif. Viene generato un errore 404 (File non trovato).

Il modulo di riscrittura URL per IIS include un aggiornamento per ASP.NET che corregge questo comportamento. L'aggiornamento fa sì che l'operatore ~ nei controlli server Web venga risolto rispetto all'URL originariamente richiesto. Nell'esempio precedente il markup HTML nella risposta conterrà il percorso URL corretto per l'elemento img, come illustrato nel markup seguente:

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

L'aggiornamento per ASP.NET si applica solo a .NET Framework 3.5 SP1 e versioni successive. Per ottenere l'aggiornamento, aggiornare .NET Framework alla versione 3.5 SP1 e quindi eseguire il programma di installazione del modulo iis URL Rewrite, che installerà l'aggiornamento ASP.NET.

Riscrittura degli URL e dei controlli di spostamento del sito

Un ASP.NET mappa del sito può essere usato per descrivere la struttura di un sito Web in modo che l'API di spostamento del sito e i controlli di spostamento del sito possano esporre una struttura del sito logica (anziché fisica). Quando si usa il modulo di riscrittura URL con un'applicazione ASP.NET che usa la struttura del sito, in genere si vuole che i controlli di spostamento funzionino in termini di struttura del sito logico che usa URL pubblici o virtuali.

Ad esempio, è possibile definire una mappa del sito come illustrato nell'esempio seguente:

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

È quindi possibile definire regole di riscrittura che eseguono le riscritture seguenti:

  • Da /Products/ a /Products.aspx
  • /Products/Hardware to /Products.aspx?category=Hardware
  • /Products/Software to /Products.aspx?category=Software

La definizione di una mappa del sito usando questi URL virtuali può causare il corretto funzionamento della classe SystemWeb.SiteMap. Quando si tenta di accedere alla proprietà SiteMap.CurrentNode in una pagina di ASP.NET, la proprietà può contenere null. Ciò può causare il funzionamento non corretto dei controlli di spostamento del sito, ad esempio SiteMapPath e Menu.

Il modulo di riscrittura URL per IIS include un aggiornamento per ASP.NET che corregge i controlli di spostamento in modo che possano usare GLI URL virtuali riscritti. Con questo aggiornamento, la proprietà SiteMap.CurrentNode farà riferimento all'OGGETTO SiteMapNode corrispondente all'URL virtuale attualmente richiesto.

L'aggiornamento per ASP.NET si applica solo a .NET Framework 3.5 SP1 e versioni successive. Per ottenere l'aggiornamento, aggiornare .NET Framework alla versione 3.5 SP1 e quindi eseguire il programma di installazione del modulo iis URL Rewrite, che installerà l'aggiornamento ASP.NET.

Impedire la riscrittura delle richieste per le risorse Web di ASP.NET

ASP.NET applicazioni Web basate su molto spesso effettuano richieste al file WebResources.axd per recuperare le risorse dell'assembly e gestirle nel Web browser. Nel server non esiste alcun file di questo tipo perché ASP.NET genera il contenuto in modo dinamico quando viene richiesto WebResources.axd. Pertanto, se si dispone di una regola di riscrittura URL che riscrive o reindirizza solo se l'URL richiesto non corrisponde a un file o a una cartella nel file system di un server Web, tale regola può riscrivere accidentalmente le richieste effettuate a WebResources.axd e quindi interrompere l'applicazione.

Questo problema può essere facilmente impedito se si aggiunge una condizione aggiuntiva alla regola di riscrittura:

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