Ricerca…


introduzione

Il routing è il modo in cui ASP.NET MVC corrisponde a un URI a un'azione. Il modulo di routing è responsabile della mappatura delle richieste di browser in arrivo a determinate azioni del controller MVC.

MVC 5 supporta un nuovo tipo di routing, chiamato routing degli attributi. Come suggerisce il nome, il routing degli attributi utilizza gli attributi per definire i percorsi. Il routing degli attributi ti offre un maggiore controllo sugli URI nella tua applicazione web.

Routing personalizzato

Il routing personalizzato fornisce un'esigenza specialistica di routing per gestire richieste in entrata specifiche.

Per definire percorsi personalizzati, tieni presente che l'ordine dei percorsi che aggiungi alla tabella del percorso è importante.

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
    // this is an advanced custom route
    // you can define custom URL with custom parameter(s) point to certain action method
    routes.MapRoute(
    "CustomEntry", // Route name
    "Custom/{entryId}", // Route pattern
    new { controller = "Custom", action = "Entry" } // Default values for defined parameters above
    );

    // this is a basic custom route
    // any custom routes take place on top before default route
    routes.MapRoute(
    "CustomRoute", // Route name
    "Custom/{controller}/{action}/{id}", // Route pattern
    new { controller = "Custom", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
    );

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // Route pattern
    new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
    );
}

controller nomi di controller e action sono riservati. Per impostazione predefinita le mappe MVC {controller} parte dell'URL alla classe <controller>Controller , quindi cerca un metodo con il nome <action> senza aggiungere suffissi.

Sebbene si possa essere tentati di creare una famiglia di percorsi utilizzando il modello {controller}/{action}/{parameter} questo modo si rende nota la struttura della propria applicazione e si rendono gli URL un po 'fragili perché la modifica del nome del controller cambia instrada e interrompe i collegamenti salvati dall'utente.

Preferisci l'impostazione del percorso esplicito:

routes.MapRoute(
    "CustomRoute", // Route name
    "Custom/Index/{id}", // Route pattern
    new { controller = "Custom", action = nameof(CustomController.Index), id = UrlParameter.Optional }
);

(non è possibile utilizzare nameof operatore nameof per il nome del controller poiché avrà un suffisso aggiuntivo Controller ) che deve essere omesso quando si imposta il nome del controller nel percorso.

Aggiunta di route personalizzate in Mvc

L'utente può aggiungere un percorso personalizzato, mappando un URL a un'azione specifica in un controller. Questo è usato per scopi di ottimizzazione dei motori di ricerca e rende leggibili gli URL.

routes.MapRoute(
  name: "AboutUsAspx", // Route name
  url: "AboutUs.aspx",  // URL with parameters
  defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional }  // Parameter defaults
);

Instradamento degli attributi in MVC

Insieme al classico metodo di definizione del percorso MVC WEB API 2 e successivamente i framework MVC 5 hanno introdotto il Attribute routing :

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
        // This enables attribute routing and must go  before other routes are added to the routing table.
        // This makes attribute routes have higher priority
        routes.MapMvcAttributeRoutes();  
    }
}

Per le rotte con lo stesso prefisso all'interno di un controller, è possibile impostare un prefisso comune per tutti i metodi di azione all'interno del controller utilizzando RoutePrefix attributo RoutePrefix .

[RoutePrefix("Custom")]
public class CustomController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    {
        ...
    }
}

RoutePrefix è facoltativo e definisce la parte dell'URL che è prefissata a tutte le azioni del controller.

Se si dispone di più percorsi, è possibile impostare un percorso predefinito catturando l'azione come parametro, quindi applicarlo per l'intero controller, a meno che non sia specificato un attributo Route specifico su determinati metodi di azione che annullano la route predefinita.

[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
    public ActionResult Index()
    {
        ...
    }

    public ActionResult Detail()
    {
        ...
    }
}

Nozioni di base sul routing

Quando richiedi l'url yourSite/Home/Index tramite un browser, il modulo di routing indirizzerà la richiesta al metodo Index azione Index della classe HomeController . Come fa a sapere di inviare la richiesta al metodo specifico di questa specifica classe? arriva la RouteTable.

Ogni applicazione ha una tabella di percorso in cui memorizza il percorso del percorso e le informazioni su dove indirizzare la richiesta. Pertanto, quando si crea l'applicazione mvc, esiste già una route predefinita registrata nella tabella di routing. Puoi vederlo nella classe RouteConfig.cs .

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   routes.MapRoute("Default", "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}

Puoi vedere che la voce ha un nome e un modello. Il modello è il modello del percorso da verificare quando arriva una richiesta. Il modello predefinito ha Home come valore del segmento url del controller e Index come valore per il segmento azione. Ciò significa che se non si inoltra esplicitamente il nome e l'azione del controller nella richiesta, verranno utilizzati questi valori predefiniti. Questo è il motivo per cui ottieni lo stesso risultato quando accedi a yourSite/Home/Index e a yourSite

Avrai notato che abbiamo un parametro chiamato id come ultimo segmento del nostro pattern di route. Ma nei valori predefiniti, specifichiamo che è facoltativo. Questo è il motivo per cui non abbiamo dovuto specificare il valore id che abbiamo provato.

Ora, torna al metodo di azione Indice in HomeController e aggiungi un parametro

public ActionResult Index(int id)
{
     return View();
}

Ora metti un breakpoint visivo in studio con questo metodo. Esegui il tuo progetto e accedi a yourSite/Home/Index/999 nel tuo browser. Il punto di interruzione verrà colpito e dovresti essere in grado di vedere che il valore 999 è ora disponibile nel parametro id .

Creazione di un secondo modello di percorso

Diciamo che vorremmo un set up in modo che lo stesso metodo di azione venga chiamato per un modello di percorso diverso. Possiamo farlo aggiungendo una nuova definizione di percorso alla tabella del percorso.

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   
   // New custom route definition added
   routes.MapRoute("MySpecificRoute",
    "Important/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional });

   //Default catch all normal route definition
   routes.MapRoute("Default", "{controller}/{action}/{id}",
             new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}

La nuova definizione che ho aggiunto ha un pattern Important/{id} dove id è di nuovo facoltativo. Ciò significa che quando richiedi yourSiteName\Important o yourSiteName\Important\888 , verrà inviato all'azione Index di HomeController.

Registrazione dell'ordine di definizione del percorso

L'ordine di registrazione del percorso è importante. È sempre necessario registrare i percorsi del percorso specifici prima del percorso predefinito generico.

Percorso tutto compreso

Supponiamo di voler avere un percorso che consenta un numero non vincolato di segmenti in questo modo:

Avremmo bisogno di aggiungere un percorso, normalmente alla fine della tabella del percorso perché questo probabilmente catturerebbe tutte le richieste, in questo modo:

routes.MapRoute("Final", "Route/{*segments}",
      new { controller = "Product", action = "View" });

Nel controller, un'azione che potrebbe gestire questo, potrebbe essere:

public void ActionResult View(string[] segments /* <- the name of the parameter must match the name of the route parameter */)
{
    // use the segments to obtain information about the product or category and produce data to the user
    // ...
}

Catch-all route per abilitare il routing lato client

È buona norma codificare lo stato di Single Page Application (SPA) nell'URL:

my-app.com/admin-spa/users/edit/id123

Ciò consente di salvare e condividere lo stato dell'applicazione.
Quando l'utente inserisce l'url nella barra degli indirizzi del browser e gli hit entrano nel server, devono ignorare la parte lato client dell'URL richiesto. Se servi la SPA come visualizzazione del rasoio renderizzata (risultato dell'azione del controller chiamata) anziché di un file html statico, puoi utilizzare una rotta catch-all:

public class AdminSpaController
{
    [Route("~/admin-spa/{clienSidePart*}")]
    ActionResult AdminSpa()
    {
        ...
    }
}

In questo caso il server restituisce solo SPA e quindi si inizializza in base al percorso. Questo approccio è più flessibile in quanto non dipende dal modulo url-rewrite .

Instradamento degli attributi nelle aree

Per utilizzare l'instradamento attributo in aree, sono necessarie le aree di registrazione e [RouteArea(...)] .

In RouteConfig.cs :

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapMvcAttributeRoutes();
        AreaRegistration.RegisterAllAreas();
    }
}

In una definizione di routing attributo controller area campione:

[RouteArea("AreaName", AreaPrefix = "AreaName")]
[RoutePrefix("SampleAreaController")]
public class SampleAreaController : Controller
{
    [Route("Index")]
    public ActionResult Index()
    {
        return View();
    }
}

Per l'utilizzo di Url.Action link in Aree:

@Url.Action("Index", "SampleAreaController", new { area = "AreaName" })


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow