Routing con più parametri tramite ASP.NET MVC


139

La nostra azienda sta sviluppando un'API per i nostri prodotti e stiamo pensando di utilizzare ASP.NET MVC. Durante la progettazione della nostra API, abbiamo deciso di utilizzare chiamate come quella di seguito per consentire all'utente di richiedere informazioni dall'API in formato XML:

http://ws.audioscrobbler.com/2.0/?method=artist.getimages&artist=cher&api_key=b25b959554ed76058ac220b7b2e0a026

Come puoi vedere, vengono passati più parametri (ie artiste api_key). In ASP.NET MVC, artistsarebbe il controller, getImagesl'azione, ma come faccio a passare più parametri a l'azione?

È possibile anche usando il formato sopra?

Risposte:


279

I parametri sono supportati direttamente in MVC semplicemente aggiungendo parametri ai metodi di azione. Data un'azione come la seguente:

public ActionResult GetImages(string artistName, string apiKey)

MVC popolerà automaticamente i parametri quando viene assegnato un URL come:

/Artist/GetImages/?artistName=cher&apiKey=XXX

Un altro caso speciale è rappresentato dai parametri "id". Qualsiasi parametro denominato ID può essere inserito nel percorso anziché nella stringa di query, quindi qualcosa di simile a:

public ActionResult GetImages(string id, string apiKey)

verrebbe popolato correttamente con un URL come il seguente:

/Artist/GetImages/cher?apiKey=XXX

Inoltre, se si hanno scenari più complicati, è possibile personalizzare le regole di routing utilizzate da MVC per individuare un'azione. Il file global.asax contiene regole di routing che possono essere personalizzate. Per impostazione predefinita, la regola è simile alla seguente:

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

Se volessi supportare un URL come

/Artist/GetImages/cher/api-key

potresti aggiungere un percorso come:

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

e un metodo come il primo esempio sopra.


1
Sto lavorando con .NET 4 e MVC. Posso solo passare un parametro nel percorso. Questo URL {controller} / {action} / {artistName} / {apikey} non corrisponde a 2 parametri per me ma genera semplicemente un errore 404. Per quanto ne so, puoi passare solo 1 parametro nel percorso. Che cosa sto facendo di sbagliato?
DavidHyogo,

1
@DavidHyogo - Stavo riscontrando lo stesso problema. Per qualsiasi motivo, anche se ho specificato l'azione predefinita, ho dovuto inserire l'azione desiderata nel mio link html, non solo nel controller e nei parametri.
Shaggy13spe,

5
@DavidHyogo: ho avuto lo stesso problema e ho scoperto che i parametri del modello di percorso devono corrispondere esattamente ai nomi dei parametri del metodo di azione, ad es. Per il percorso definito come {controller} / {action} / {artistName} / {apikey} il metodo di azione dovrebbe avere la firma public ActionResult MyMethod (string artistName, string apikey)
Sudhanshu Mishra,

6
Inoltre, assicurati che il tuo URL non venga catturato dal percorso predefinito prima che raggiunga quello personalizzato. Utilizzerà la prima corrispondenza in base a come li hai definiti. Nel mio caso, stavo cercando di utilizzare la route "MyController / {year} / {month}" per impostazione predefinita di Index, ma la route {controller} / {action} / {id} corrispondeva al mio URL (MyController / 2015 / 04), quindi stavo ottenendo un 404 perché non esisteva alcuna azione con il nome 2015. Spostando il mio percorso personalizzato verso l'alto risolto il problema.
Sam,

Il nome dei parametri nel routeconfig non corrispondeva alla mia firma Action, ecco perché non funzionava, ho seguito i passaggi descritti da @dotnetguy e ha funzionato
pepitomb,

26

A partire da MVC 5, è anche possibile utilizzare il routing degli attributi per spostare la configurazione dei parametri URL sui controller.

Una discussione dettagliata è disponibile qui: http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx

Sommario:

Innanzitutto abilitare il routing degli attributi

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

         routes.MapMvcAttributeRoutes();
     } 
 }

Quindi è possibile utilizzare gli attributi per definire i parametri e, facoltativamente, i tipi di dati

public class BooksController : Controller
{
    // eg: /books
    // eg: /books/1430210079
    [Route("books/{isbn?}")]
    public ActionResult View(string isbn)

5
Il routing degli attributi in ASP.NET Core MVC è descritto in docs.microsoft.com/en-us/aspnet/core/mvc/controllers/…
Bernard Vander Beken l'

21

È possibile passare parametri arbitrari attraverso la stringa di query, ma è anche possibile impostare percorsi personalizzati per gestirlo in modo RESTful:

http://ws.audioscrobbler.com/2.0/?method=artist.getimages&artist=cher&
                                  api_key=b25b959554ed76058ac220b7b2e0a026

Potrebbe essere:

routes.MapRoute(
    "ArtistsImages",
    "{ws}/artists/{artist}/{action}/{*apikey}",
    new { ws = "2.0", controller="artists" artist = "", action="", apikey="" }
    );

Quindi, se qualcuno ha utilizzato il seguente percorso:

ws.audioscrobbler.com/2.0/artists/cher/images/b25b959554ed76058ac220b7b2e0a026/

Li porterebbe nello stesso posto del tuo esempio di querystring.

Quanto sopra è solo un esempio e non applica le regole e i vincoli aziendali che dovresti impostare per assicurarti che le persone non abbiano "hackerato" l'URL.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.