Routing in ASP.NET Web API (in inglese)

Questo articolo descrive come API Web ASP.NET instrada le richieste HTTP ai controller.

Nota

Se si ha familiarità con ASP.NET MVC, il routing dell'API Web è molto simile al routing MVC. La differenza principale è che l'API Web usa il verbo HTTP, non il percorso URI, per selezionare l'azione. È anche possibile usare il routing in stile MVC nell'API Web. Questo articolo non presuppone alcuna conoscenza di ASP.NET MVC.

Tabelle di routing

In API Web ASP.NET un controller è una classe che gestisce le richieste HTTP. I metodi pubblici del controller sono chiamati metodi di azione o semplicemente azioni. Quando il framework API Web riceve una richiesta, instrada la richiesta a un'azione.

Per determinare quale azione richiamare, il framework usa una tabella di routing. Il modello di progetto di Visual Studio per l'API Web crea una route predefinita:

routes.MapHttpRoute(
    name: "API Default",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

Questa route è definita nel file WebApiConfig.cs , che viene inserito nella directory App_Start :

Immagine di Esplora soluzioni in cui vengono definite le route.

Per altre informazioni sulla WebApiConfig classe , vedere Configurazione di API Web ASP.NET.

Se si ospita l'API Web self-host, è necessario impostare la tabella di routing direttamente sull'oggetto HttpSelfHostConfiguration . Per altre informazioni, vedere Self-host di un'API Web.

Ogni voce nella tabella di routing contiene un modello di route. Il modello di route predefinito per l'API Web è "api/{controller}/{id}". In questo modello "api" è un segmento di percorso letterale e {controller} e {id} sono variabili segnaposto.

Quando il framework API Web riceve una richiesta HTTP, tenta di trovare la corrispondenza con l'URI rispetto a uno dei modelli di route nella tabella di routing. Se nessuna route corrisponde, il client riceve un errore 404. Ad esempio, gli URI seguenti corrispondono alla route predefinita:

  • /api/contacts
  • /api/contacts/1
  • /api/products/gizmo1

Tuttavia, l'URI seguente non corrisponde, perché manca il segmento "api":

  • /contacts/1

Nota

Il motivo dell'uso di "api" nella route consiste nell'evitare conflitti con ASP.NET routing MVC. In questo modo, è possibile avere "/contatti" passare a un controller MVC e "/api/contatti" passare a un controller API Web. Naturalmente, se non si preferisce questa convenzione, è possibile modificare la tabella di route predefinita.

Dopo aver trovato una route corrispondente, l'API Web seleziona il controller e l'azione:

  • Per trovare il controller, l'API Web aggiunge "Controller" al valore della variabile {controller} .
  • Per trovare l'azione, l'API Web esamina il verbo HTTP e quindi cerca un'azione il cui nome inizia con il nome del verbo HTTP. Ad esempio, con una richiesta GET, l'API Web cerca un'azione preceduta da "Get", ad esempio "GetContact" o "GetAllContacts". Questa convenzione si applica solo ai verbi GET, POST, PUT, DELETE, HEAD, OPTIONS e PATCH. È possibile abilitare altri verbi HTTP usando attributi nel controller. Più avanti verrà illustrato un esempio.
  • Altre variabili segnaposto nel modello di route, ad esempio {id}, vengono mappate ai parametri di azione.

Di seguito è descritto un esempio. Si supponga di definire il controller seguente:

public class ProductsController : ApiController
{
    public IEnumerable<Product> GetAllProducts() { }
    public Product GetProductById(int id) { }
    public HttpResponseMessage DeleteProduct(int id){ }
}

Ecco alcune possibili richieste HTTP, insieme all'azione che viene richiamata per ognuna:

Verbo HTTP Percorso URI Azione Parametro
GET api/products GetAllProducts (nessuno)
GET api/products/4 GetProductById 4
DELETE api/products/4 DeleteProduct 4
POST api/products (nessuna corrispondenza)

Si noti che il segmento {id} dell'URI, se presente, viene mappato al parametro id dell'azione. In questo esempio il controller definisce due metodi GET, uno con un parametro ID e uno senza parametri.

Si noti inoltre che la richiesta POST avrà esito negativo perché il controller non definisce un metodo "Post...".

Varianti di routing

Nella sezione precedente è stato descritto il meccanismo di routing di base per API Web ASP.NET. In questa sezione vengono descritte alcune varianti.

Verbi HTTP

Anziché usare la convenzione di denominazione per i verbi HTTP, è possibile specificare in modo esplicito il verbo HTTP per un'azione decorata con uno degli attributi seguenti:

  • [HttpGet]
  • [HttpPut]
  • [HttpPost]
  • [HttpDelete]
  • [HttpHead]
  • [HttpOptions]
  • [HttpPatch]

Nell'esempio seguente viene eseguito il mapping del FindProduct metodo alle richieste GET:

public class ProductsController : ApiController
{
    [HttpGet]
    public Product FindProduct(id) {}
}

Per consentire più verbi HTTP per un'azione o per consentire verbi HTTP diversi da GET, PUT, POST, DELETE, HEAD, OPTIONS e PATCH, usare l'attributo [AcceptVerbs] , che accetta un elenco di verbi HTTP.

public class ProductsController : ApiController
{
    [AcceptVerbs("GET", "HEAD")]
    public Product FindProduct(id) { }

    // WebDAV method
    [AcceptVerbs("MKCOL")]
    public void MakeCollection() { }
}

Routing per nome azione

Con il modello di routing predefinito, l'API Web usa il verbo HTTP per selezionare l'azione. Tuttavia, è anche possibile creare una route in cui il nome dell'azione è incluso nell'URI:

routes.MapHttpRoute(
    name: "ActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

In questo modello di route il parametro {action} assegna un nome al metodo di azione nel controller. Con questo stile di routing, usare gli attributi per specificare i verbi HTTP consentiti. Si supponga, ad esempio, che il controller abbia il metodo seguente:

public class ProductsController : ApiController
{
    [HttpGet]
    public string Details(int id);
}

In questo caso, una richiesta GET per "api/products/details/1" viene mappata al Details metodo . Questo stile di routing è simile a ASP.NET MVC e può essere appropriato per un'API in stile RPC.

È possibile eseguire l'override del nome dell'azione usando l'attributo [ActionName] . Nell'esempio seguente sono presenti due azioni che eseguono il mapping a "api/products/thumbnail/id. Uno supporta GET e l'altro supporta POST:

public class ProductsController : ApiController
{
    [HttpGet]
    [ActionName("Thumbnail")]
    public HttpResponseMessage GetThumbnailImage(int id);

    [HttpPost]
    [ActionName("Thumbnail")]
    public void AddThumbnailImage(int id);
}

Azioni non

Per impedire che un metodo venga richiamato come azione, usare l'attributo [NonAction] . Questo segnala al framework che il metodo non è un'azione, anche se altrimenti corrisponde alle regole di routing.

// Not an action method.
[NonAction]  
public string GetPrivateData() { ... }

Altre informazioni

In questo argomento è stata fornita una visualizzazione generale del routing. Per altri dettagli, vedere Routing e selezione delle azioni, che descrive esattamente come il framework corrisponde a un URI a una route, seleziona un controller e quindi seleziona l'azione da richiamare.