Il presente articolo è stato tradotto manualmente. Passare il puntatore sulle frasi nell'articolo per visualizzare il testo originale.
Traduzione
Originale
1 di 2 hanno valutato il contenuto utile: - Valuta questo argomento

Routing di ASP.NET

Il routing di ASP.NET consente di utilizzare URL di cui non è necessario eseguire il mapping a specifici file in un sito Web. Di conseguenza, è possibile utilizzare URL in cui è descritta l'azione dell'utente e pertanto più facilmente comprensibili da parte di quest'ultimo.

Il framework di MVC ASP.NET e ASP.NET Dynamic Data consentono di estendere il routing per fornire funzionalità utilizzate solo nelle applicazioni MVC e Dynamic Data. Per ulteriori informazioni su ASP.NET MVC, vedere la pagina relativa a ASP.NET MVC. Per ulteriori informazioni su Dynamic Data, vedere Mappa del contenuto per ASP.NET Dynamic Data.

In un'applicazione ASP.NET che non consente di utilizzare il routing, in genere una richiesta in entrata di un URL viene mappata a un file fisico tramite cui viene gestita la richiesta, ad esempio un file con estensione aspx. Ad esempio, nel caso di una richiesta per http://server/application/Products.aspx?id=4, ne viene eseguito il mapping a un file denominato Products.aspx che contiene codice e markup per il rendering di una risposta nel browser. Nella pagina Web viene utilizzato il valore della stringa di query id=4 per determinare il tipo di contenuto da visualizzare.

Nel routing di ASP.NET, è possibile definire i modelli di URL che vengono mappati ai file del gestore di richieste, ma nei quali non sono necessariamente inclusi i nomi di tali file. Inoltre, in un modello di URL è possibile includere segnaposto in modo che i dati della variabile possano essere passati al gestore di richieste senza richiedere una stringa di query.

Ad esempio, nella richiesta per http://server/application/Products/show/beverages, il parser di routing può passare i valori Products, show e beverages a un gestore di pagina. In questo esempio, se la route è definita tramite il modello di URL server/application/{area}/{action}/{category}, il gestore di pagina riceverebbe un insieme di dizionari in cui il valore associato alla chiave area è Products, il valore della chiave action è show e il valore della chiave category è beverages. In una richiesta non gestita dal routing di URL, il frammento /Products/show/beverages verrebbe interpretato come percorso di un file nell'applicazione.

In questo argomento sono incluse le sezioni seguenti:

Una route è un modello di URL mappato a un gestore. Il gestore può essere un file fisico, ad esempio un file con estensione aspx in un'applicazione Web Form. Un gestore può essere anche una classe tramite cui viene elaborata la richiesta, ad esempio un controller in un'applicazione MVC. Per definire una route, è necessario creare un'istanza della classe Route specificando il modello di URL, il gestore e facoltativamente un nome per la route.

La route deve essere aggiunta all'applicazione aggiungendo l'oggetto Route alla proprietà Routes statica della classe RouteTable. La proprietà Routes è un oggetto RouteCollection che consente di archiviare tutte le route per l'applicazione.

In genere, non è necessario scrivere codice per aggiungere route in un'applicazione MVC. Nei modelli di progetto di Visual Studio per MVC sono incluse le route dell'URL preconfigurate. Queste ultime vengono definite nella classe MvcApplication, specificata nel file Global.asax.

In un modello di URL possono essere contenuti valori letterali e segnaposto di variabili (definiti parametri URL). I valori letterali e i segnaposto si trovano nei segmenti dell'URL i quali sono delimitati dal carattere barra (/).

Quando viene effettuata una richiesta, l'URL viene analizzato in segmenti e segnaposto e i valori della variabile vengono forniti al gestore di richieste. Questo processo è simile al modo in cui i dati nelle stringhe di query vengono analizzati e passati al gestore di richieste. In entrambi i casi le informazioni variabili sono incluse nell'URL e vengono passate al gestore sotto forma di coppie chiave-valore. Per le stringhe di query, le chiavi e i valori si trovano nell'URL. Per le route, le chiavi sono i nomi dei segnaposto definiti nel modello di URL e solo i valori si trovano nell'URL.

In un modello di URL, i segnaposto vengono definiti includendoli tra parentesi graffe ( { e } ). In un segmento è possibile definire più segnaposto, ma devono essere separati da un valore letterale. Ad esempio, {language}-{country}/{action} è un modello di route valido, mentre {language}{country}/{action} non è un modello valido in quanto non sono presenti valore letterali o delimitatori tra i segnaposto. Pertanto, il routing non è in grado di determinare la posizione in cui separare il valore del segnaposto language dal valore del segnaposto country.

Nella tabella riportata di seguito vengono illustrati modelli di route validi ed esempi di richieste di URL che corrispondono ai modelli.

Definizione di route

Esempio di URL corrispondente

{controller}/{action}/{id}

/Products/show/beverages

{table}/Details.aspx

/Products/Details.aspx

blog/{action}/{entry}

/blog/show/123

{reporttype}/{year}/{month}/{day}

/sales/2008/1/5

{locale}/{action}

/US/show

{language}-{country}/{action}

/en-US/show

Modelli di URL tipici nelle applicazioni MVC

In genere, nei modelli di URL per le route delle applicazioni MVC sono inclusi i segnaposto {controller} e {action}.

Una volta ricevuta, una richiesta viene indirizzata all'oggetto UrlRoutingModule, quindi al gestore HTTP MvcHandler. Il gestore HTTP MvcHandler consente di determinare il controller da richiamare aggiungendo il suffisso "Controller" al relativo valore nell'URL per determinare il nome del tipo di controller tramite cui verrà gestita la richiesta. Il valore dell'azione nell'URL consente di determinare il metodo di azione da chiamare.

Ad esempio, un URL in cui è incluso il relativo percorso /Products viene mappato a un controller denominato ProductsController. Il valore nel parametro action è il nome del metodo di azione chiamato. Un URL in cui è incluso il relativo percorso /Products/show comporterebbe una chiamata al metodo Show della classe ProductsController.

Nella tabella seguente vengono mostrati i modelli di URL predefiniti ed esempi di richieste URL gestite dalle route predefinite.

Modello di URL predefinito

Esempi di URL corrispondenti

{controller}/{action}/{id}

http://server/application/Products/show/beverages

{resource}.axd/{*pathInfo}

http://server/application/WebResource.axd?d=...

La route con il modello {resource}.axd/{*pathInfo} viene inclusa per evitare che le richieste per i file di risorse Web, ad esempio WebResource.axd o ScriptResource.axd, vengano passate a un controller.

Per IIS 7.0, non è necessaria alcuna estensione di file. Per IIS 6.0, è necessario aggiungere l'estensione di file mvc al modello di URL, come mostrato nell'esempio seguente:

{controller}.mvc/{action}/{id}

In un'applicazione Web Form, le route vengono create tramite il metodo MapPageRoute(String, String, String) della classe RouteCollection. Il metodo MapPageRoute consente di creare un oggetto Route e di aggiungerlo all'oggetto RouteCollection. Le proprietà per l'oggetto Route vengono specificate nei parametri passati al metodo MapPageRoute.

In genere, si aggiungono route in un metodo chiamato dal gestore dell'evento Application_Start nel file Global.asax. Questo approccio garantisce la disponibilità delle route quando viene avviata l'applicazione e consente, inoltre, di chiamare il metodo direttamente quando si esegue lo unit test dell'applicazione. Se si desidera chiamare direttamente un metodo durante l'esecuzione dello unit test dell'applicazione, il metodo che consente di registrare le route deve essere statico (Shared in Visual Basic) e deve disporre di un parametro RouteCollection.

Nell'esempio riportato di seguito viene illustrato il codice di un file Global.asax in cui viene aggiunto un oggetto Route che definisce due parametri URL denominati action e categoryName. Gli URL che dispongono del modello specificato vengono diretti alla pagina fisica denominata Categories.aspx.

protected void Application_Start(object sender, EventArgs e)
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx");
}

Se si adotta la convenzione MVC che prevede l'implementazione dei controller tramite la creazione di classi che derivano dalla classe ControllerBase e l'assegnazione di nomi che terminano con "Controller", non è necessario aggiungere manualmente route in un'applicazione MVC. Le route preconfigurate consentiranno di richiamare i metodi di azione implementati nelle classi controller.

Se si desidera aggiungere route personalizzate in un'applicazione MVC, è necessario utilizzare il metodo MapRoute(RouteCollection, String, String) anziché il metodo MapPageRoute(String, String, String).

Nell'esempio seguente viene mostrato il codice che consente di creare route MVC predefinite nel file Global.asax, come definito nel modello di progetto di Visual Studio per le applicazioni MVC.


public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}


Quando si definisce una route, è possibile assegnare un valore predefinito per un parametro. Il valore predefinito viene utilizzato se nell'URL non è incluso un valore per tale parametro. I valori predefiniti per una route vengono impostati assegnando un oggetto dizionario alla proprietà Defaults della classe Route. Nell'esempio seguente viene illustrato come aggiungere una route che dispone di valori predefiniti utilizzando il metodo MapPageRoute(String, String, String, Boolean, RouteValueDictionary).

void Application_Start(object sender, EventArgs e) 
{
    RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary 
            {{"categoryName", "food"}, {"action", "show"}});
}

Quando il routing di ASP.NET gestisce una richiesta di URL, la definizione di route illustrata nell'esempio (con i valori predefiniti food per categoryName e show per action) produce i risultati elencati nella tabella riportata di seguito.

URL

Valori di parametri.

/Category

action = "show" (valore predefinto)

categoryName = "food" (valore predefinito)

/Category/add

action = "add"

categoryName = "food" (valore predefinito)

/Category/add/beverages

action = "add"

categoryName = "beverages"

Per le applicazioni MVC, gli overload del metodo RouteCollectionExtensions.MapRoute, ad esempio MapRoute(RouteCollection, String, String, Object, Object) consentono di specificare le impostazioni predefinite.

Talvolta è necessario gestire richieste di URL che contengono un numero variabile di segmenti di URL. Quando si definisce una route, è possibile specificare che se un URL dispone di più segmenti rispetto al modello, i segmenti aggiuntivi vengano considerati parte integrante dell'ultimo segmento. Per gestire i segmenti aggiuntivi in questo modo, è necessario contrassegnare l'ultimo parametro con un asterisco (*). Tale parametro viene definito catch-all. Una route con un parametro catch-all corrisponderà anche agli URL che non contengono valori per l'ultimo parametro. Nell'esempio riportato di seguito viene illustrato un modello di route che corrisponde a un numero sconosciuto di segmenti.

query/{queryname}/{*queryvalues}

Quando il routing di ASP.NET gestisce una richiesta di URL, la definizione di route illustrata nell'esempio produce i risultati elencati nella tabella riportata di seguito.

URL

Valori di parametri.

/query/select/bikes/onsale

nomequery = "select"

valoriquery = "bikes/onsale"

/query/select/bikes

nomequery = "select"

valoriquery = "bikes"

/query/select

nomequery = "select"

valoriquery = stringa vuota

Oltre alla corrispondenza di una richiesta di URL a una definizione di route in base al numero di parametri nell'URL, è possibile specificare che i valori nei parametri soddisfino determinati vincoli. Se un URL contiene valori al di fuori dei vincoli di una route, tale route non viene utilizzata per gestire la richiesta. I vincoli vengono aggiunti per assicurarsi che i parametri URL contengano valori che verranno utilizzati nell'applicazione.

I vincoli vengono definiti mediante espressioni regolari o oggetti che implementano l'interfaccia IRouteConstraint. Quando si aggiunge la definizione di route all'insieme Routes, i vincoli vengono aggiunti mediante la creazione di un oggetto RouteValueDictionary che contiene il test di verifica. La chiave nel dizionario identifica il parametro a cui si applica il vincolo. Il valore nel dizionario può essere una stringa che rappresenta un'espressione regolare o un oggetto che implementa l'interfaccia IRouteConstraint.

Se si fornisce una stringa, il routing la considera come espressione regolare e controlla l'eventuale validità del valore di parametro chiamando il metodo IsMatch della classe Regex. L'espressione regolare viene considerata sempre come priva di distinzione tra maiuscole e minuscole. Per ulteriori informazioni, vedere Espressioni regolari di .NET Framework.

Se si fornisce un oggetto IRouteConstraint, il routing di ASP.NET controlla l'eventuale validità del valore di parametro chiamando il metodo Match dell'oggetto IRouteConstraint. Il metodo Match restituisce un valore Boolean che indica se il valore di parametro è valido.

Nell'esempio seguente viene mostrato come utilizzare il metodo MapPageRoute per creare una route che dispone di vincoli che consentono di limitare i valori che possono essere inclusi nei parametri locale e year (in un'applicazione MVC, si utilizzerebbe il metodo MapRoute).

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapPageRoute("",
        "Category/{action}/{categoryName}",
        "~/categoriespage.aspx",
        true,
        new RouteValueDictionary 
            {{"categoryName", "food"}, {"action", "show"}},
        new RouteValueDictionary 
            {{"locale", "[a-z]{2}-[a-z]{2}"},{"year", @"\d{4}"}}
       );
}

Quando il routing gestisce una richiesta di URL, la definizione di route illustrata nell'esempio precedente produce i risultati elencati nella tabella riportata di seguito.

URL

Risultato

/US

Nessuna corrispondenza. Sono necessari sia locale sia year.

/US/08

Nessuna corrispondenza. Il vincolo su year richiede 4 cifre.

/US/2008

locale = "US"

year = "2008"

In alcune circostanze, il routing di ASP.NET non consente di gestire una richiesta anche se è abilitato per il sito Web. In questa sezione vengono descritti alcuni scenari nei quali il routing non consente di gestire la richiesta.

Viene trovato un file fisico che corrisponde al modello di URL

Per impostazione predefinita, il routing non gestisce richieste di cui viene eseguito il mapping a un file fisico esistente sul server Web. Ad esempio, una richiesta per http://server/application/Products/Beverages/Coffee.aspx non viene gestita dal routing se esiste un file fisico in corrispondenza di Products/Beverages/Coffee.aspx. Il routing non consente di gestire la richiesta anche se quest'ultima corrisponde a un modello definito, ad esempio {controller}/{action}/{id}.

Se si desidera che tutte le richieste vengano gestite dal routing, anche quelle che puntano a file, è possibile eseguire l'override del comportamento predefinito impostando la proprietà RouteExistingFiles dell'oggetto RouteCollection su true. Quando si imposta questo valore su true, tutte le richieste che corrispondono a un modello definito vengono gestite dal routing.

Il routing viene disabilitato in modo esplicito per un modello di URL

È anche possibile specificare che il routing non gestisca determinate richieste di URL. Per impedire che il routing gestisca determinate richieste, è necessario definire una route e specificare che la classe StopRoutingHandler venga utilizzata per gestire tale modello. Quando una richiesta viene gestita da un oggetto StopRoutingHandler, l'oggetto StopRoutingHandler blocca tutte le altre elaborazioni della richiesta come route. La richiesta viene invece elaborata come pagina ASP.NET, servizio Web o altro endpoint ASP.NET. È possibile utilizzare il metodo RouteCollection.Ignore (o RouteCollectionExtensions.IgnoreRoute per le applicazioni MVC) per creare route nelle quali viene utilizzata la classe StopRoutingHandler. Nell'esempio seguente viene mostrato come evitare che le richieste per il file WebResource.axd vengano gestite dal routing.

public static void RegisterRoutes(RouteCollection routes)
{
  routes.Ignore("{resource}.axd/{*pathInfo}");
}

Quando il routing gestisce le richieste di URL, tenta di creare una corrispondenza tra l'URL della richiesta e una route. La corrispondenza tra una richiesta di URL e una route dipende da tutte le seguenti condizioni:

  • Modelli di route definiti dall'utente o modelli di route predefiniti, se presenti, inclusi nel tipo di progetto.

  • Ordine in cui sono stati aggiunti all'insieme Routes.

  • Eventuali valori predefiniti forniti per una route.

  • Eventuali vincoli forniti per una route.

  • Eventuale definizione del routing per la gestione delle richieste che corrispondono a un file fisico.

Per evitare che una richiesta venga gestita dal gestore errato, è necessario considerare tutte queste condizioni quando si definiscono le route. L'ordine in cui gli oggetti Route vengono visualizzati nell'insieme Routes è significativo. La corrispondenza a una route viene tentata dalla prima all'ultima route nell'insieme e, quando si verifica, non vengono valutate altre route. In generale, è consigliabile aggiungere route alla proprietà Routes in un ordine che va dalle definizioni di route più specifiche a quelle meno specifiche.

Ad esempio, si supponga di aggiungere route con i seguenti modelli:

  • La route 1 è impostata su {controller}/{action}/{id}.

  • La route 2 è impostata su products/show/{id}.

La route 2 non consentirà mai di gestire una richiesta poiché la route 1 viene valutata per prima e corrisponderà sempre alle richieste che potrebbero funzionare anche per la route 2. Una richiesta per http://server/application/products/show/bikes sembra corrispondere di più alla route 2, tuttavia viene gestita dalla route 1 con i valori seguenti:

  • controller è products.

  • action è show.

  • id è bikes.

I valori predefiniti vengono utilizzati se manca un parametro nella richiesta. Pertanto, tali valori possono determinare la corrispondenza tra una route e una richiesta non prevista. Ad esempio, si supponga di aggiungere route con i seguenti modelli:

  • Route 1: {report}/{year}/{month}, con valori predefiniti per year e month.

  • Route 2: {report}/{year}, con un valore predefinito per year.

La route 2 non gestirà mai una richiesta. La route 1 potrebbe essere destinata a un report mensile, mentre la route 2 a un report annuale. Tuttavia, i valori predefiniti nella route 1 indicano che quest'ultima corrisponderà a qualsiasi richiesta che potrebbe essere valida anche per la route 2.

È possibile evitare l'ambiguità nei modelli includendo costanti, quali annual/{report}/{year} e monthly/{report}/{year}/{month}.

Se un URL non corrisponde ad alcun oggetto Route definito nell'insieme RouteTable, il routing di ASP.NET non elabora la richiesta. L'elaborazione viene invece passata a una pagina ASP.NET, a un servizio Web o a un altro endpoint ASP.NET.

Se si desidera creare collegamenti ipertestuali alle pagine del sito, è possibile utilizzare i modelli di URL per creare a livello di codice URL che corrispondano alle route. Quando si modificano i modelli, gli URL che corrispondono ai nuovi modelli saranno generati automaticamente. Per informazioni sulla generazione di URL nel codice o nel markup, vedere Procedura: costruire URL dalle route.

Nel gestore per una richiesta di pagina con routing è possibile accedere ai valori passati nei segnaposto URL tramite il codice o il markup. Per ulteriori informazioni, vedere Procedura: accedere ai parametri URL in una pagina con routing.

Per le applicazioni MVC, i valori passati nei segnaposto URL vengono gestiti automaticamente dal framework di MVC. Per ulteriori informazioni, vedere Passaggio di dati in un'applicazione MVC ASP.NET.

Le regole di autorizzazione possono essere applicate solo all'URL della route oppure sia all'URL della route sia all'URL fisico a cui viene mappato. Ad esempio, le regole di autorizzazione potrebbero specificare che tutti gli utenti possono accedere agli URL che iniziano con Category ma che solo gli amministratori possono accedere alla pagina Categories.aspx. Se il modello di URL della route contoso.com/Category/{controller}/{action} è mappato all'URL fisico contoso.com/Categoriespage.aspx e le regole di autorizzazione vengono applicate solo all'URL della route, l'accesso alla pagina Categoriespage.aspx sarà consentito a tutti gli utenti, se richiesto tramite un URL della route. Tuttavia, solo gli amministratori potranno accedervi se la richiesta viene effettuata tramite un URL fisico.

Per impostazione predefinita, le regole di autorizzazione vengono applicate sia all'URL della route sia all'URL fisico. Per ulteriori informazioni, vedere la proprietà PageRouteHandler.CheckPhysicalUrlAccess.

Nella tabella seguente vengono elencate le classi server principali per il routing di ASP.NET.

Classe

Descrizione

Route

Rappresenta una route in un'applicazione Web Form o MVC.

DynamicDataRoute

Rappresenta una route in un'applicazione Dynamic Data.

RouteBase

Funge da classe base per tutte le classi che rappresentano una route ASP.NET.

RouteTable

Archivia le route per un'applicazione.

RouteCollection

Fornisce metodi che consentono di gestire un insieme di route.

RouteCollectionExtensions

Fornisce metodi aggiuntivi che consentono di gestire un insieme di route nelle applicazioni MVC.

RouteData

Contiene i valori per una route richiesta.

RequestContext

Contiene le informazioni sulla richiesta HTTP che corrisponde alla route.

StopRoutingHandler

Fornisce un modo per specificare al routing ASP.NET di non gestire le richieste per un modello di URL.

PageRouteHandler

Fornisce un modo per definire le route per le applicazioni Web Form.

RouteValueDictionary

Fornisce un modo per archiviare gli oggetti route Constraints, Defaults e DataTokens.

VirtualPathData

Fornisce un modo per generare URL dalle informazioni sulla route.

Il routing di ASP.NET è diverso dalla riscrittura di URL Nella riscrittura degli URL le richieste in entrata vengono elaborate mediante la modifica effettiva dell'URL prima che questo invii la richiesta alla pagina Web. Ad esempio, in un'applicazione che utilizza la riscrittura degli URL, un URL potrebbe essere modificato da /Products/Widgets/ in /Products.aspx?id=4. Inoltre, la riscrittura degli URL non dispone in genere di un'API per la creazione di URL basati su modelli personalizzati. Pertanto, se si modifica un modello di URL, è necessario aggiornare manualmente tutti i collegamenti ipertestuali che contengono l'URL originale.

Con il routing di ASP.NET, l'URL non viene modificato durante la gestione di una richiesta in entrata, poiché il routing può estrarre i valori dall'URL. Quando è necessario creare un URL, è possibile passare i valori di parametro in un metodo che genera l'URL automaticamente. Per modificare il modello di URL, è sufficiente modificarlo in un solo percorso e tutti i collegamenti creati nell'applicazione e basati su tale modello utilizzeranno automaticamente il nuovo modello.

Il documento è risultato utile?
(1500 caratteri rimanenti)

Aggiunte alla community

AGGIUNGI
© 2013 Microsoft. Tutti i diritti riservati.