Roteamento no ASP.NET Web API
Este artigo descreve como ASP.NET Web API roteia solicitações HTTP para controladores.
Observação
Se você estiver familiarizado com ASP.NET MVC, o roteamento de API Web será muito semelhante ao roteamento MVC. A diferença main é que a API Web usa o verbo HTTP, não o caminho do URI, para selecionar a ação. Você também pode usar o roteamento no estilo MVC na API Web. Este artigo não pressupõe nenhum conhecimento de ASP.NET MVC.
Tabelas de roteamento
Em ASP.NET Web API, um controlador é uma classe que manipula solicitações HTTP. Os métodos públicos do controlador são chamados de métodos de ação ou simplesmente ações. Quando a estrutura da API Web recebe uma solicitação, ela encaminha a solicitação para uma ação.
Para determinar qual ação invocar, a estrutura usa uma tabela de roteamento. O modelo de projeto do Visual Studio para API Web cria uma rota padrão:
routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Essa rota é definida no arquivo WebApiConfig.cs , que é colocado no diretório App_Start :
Para obter mais informações sobre a WebApiConfig
classe , consulte Configurando ASP.NET Web API.
Se você auto-hospedar a API Web, deverá definir a tabela de roteamento diretamente no HttpSelfHostConfiguration
objeto . Para obter mais informações, consulte Auto-hospedar uma API Web.
Cada entrada na tabela de roteamento contém um modelo de rota. O modelo de rota padrão para a API Web é "api/{controller}/{id}". Neste modelo, "api" é um segmento de caminho literal e {controller} e {id} são variáveis de espaço reservado.
Quando a estrutura da API Web recebe uma solicitação HTTP, ela tenta corresponder o URI com um dos modelos de rota na tabela de roteamento. Se nenhuma rota corresponder, o cliente receberá um erro 404. Por exemplo, os seguintes URIs correspondem à rota padrão:
- /api/contacts
- /api/contacts/1
- /api/products/gizmo1
No entanto, o URI a seguir não corresponde, pois ele não tem o segmento "api":
- /contacts/1
Observação
O motivo para usar a "api" na rota é evitar colisões com ASP.NET roteamento MVC. Dessa forma, você pode fazer com que "/contacts" acessem um controlador MVC e "/api/contacts" acesse um controlador de API Web. É claro que, se você não gostar dessa convenção, poderá alterar a tabela de rotas padrão.
Depois que uma rota correspondente é encontrada, a API Web seleciona o controlador e a ação:
- Para localizar o controlador, a API Web adiciona "Controller" ao valor da variável {controller }.
- Para localizar a ação, a API Web examina o verbo HTTP e procura uma ação cujo nome começa com esse nome de verbo HTTP. Por exemplo, com uma solicitação GET, a API Web procura uma ação prefixada com "Get", como "GetContact" ou "GetAllContacts". Essa convenção se aplica somente aos verbos GET, POST, PUT, DELETE, HEAD, OPTIONS e PATCH. Você pode habilitar outros verbos HTTP usando atributos no controlador. Veremos um exemplo disso mais tarde.
- Outras variáveis de espaço reservado no modelo de rota, como {id}, são mapeadas para parâmetros de ação.
Vamos examinar um exemplo. Suponha que você defina o seguinte controlador:
public class ProductsController : ApiController
{
public IEnumerable<Product> GetAllProducts() { }
public Product GetProductById(int id) { }
public HttpResponseMessage DeleteProduct(int id){ }
}
Aqui estão algumas solicitações HTTP possíveis, juntamente com a ação que é invocada para cada uma:
Verbo HTTP | Caminho do URI | Ação | Parâmetro |
---|---|---|---|
GET | api/products | GetAllProducts | (none) |
GET | api/products/4 | GetProductById | 4 |
Delete (excluir) | api/products/4 | DeleteProduct | 4 |
POST | api/products | (sem correspondência) |
Observe que o segmento {id} do URI, se presente, é mapeado para o parâmetro id da ação. Neste exemplo, o controlador define dois métodos GET, um com um parâmetro id e outro sem parâmetros.
Além disso, observe que a solicitação POST falhará, pois o controlador não define um método "Post...".
Variações de roteamento
A seção anterior descreveu o mecanismo de roteamento básico para ASP.NET Web API. Esta seção descreve algumas variações.
Verbos HTTP
Em vez de usar a convenção de nomenclatura para verbos HTTP, você pode especificar explicitamente o verbo HTTP para uma ação decorando o método de ação com um dos seguintes atributos:
[HttpGet]
[HttpPut]
[HttpPost]
[HttpDelete]
[HttpHead]
[HttpOptions]
[HttpPatch]
No exemplo a seguir, o FindProduct
método é mapeado para solicitações GET:
public class ProductsController : ApiController
{
[HttpGet]
public Product FindProduct(id) {}
}
Para permitir vários verbos HTTP para uma ação ou permitir verbos HTTP diferentes de GET, PUT, POST, DELETE, HEAD, OPTIONS e PATCH, use o [AcceptVerbs]
atributo , que usa uma lista de verbos HTTP.
public class ProductsController : ApiController
{
[AcceptVerbs("GET", "HEAD")]
public Product FindProduct(id) { }
// WebDAV method
[AcceptVerbs("MKCOL")]
public void MakeCollection() { }
}
Roteamento por nome da ação
Com o modelo de roteamento padrão, a API Web usa o verbo HTTP para selecionar a ação. No entanto, você também pode criar uma rota em que o nome da ação está incluído no URI:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Neste modelo de rota, o parâmetro {action} nomeia o método de ação no controlador. Com esse estilo de roteamento, use atributos para especificar os verbos HTTP permitidos. Por exemplo, suponha que o controlador tenha o seguinte método:
public class ProductsController : ApiController
{
[HttpGet]
public string Details(int id);
}
Nesse caso, uma solicitação GET para "api/products/details/1" seria mapeada para o Details
método . Esse estilo de roteamento é semelhante a ASP.NET MVC e pode ser apropriado para uma API no estilo RPC.
Você pode substituir o nome da ação usando o [ActionName]
atributo . No exemplo a seguir, há duas ações que são mapeadas para "api/products/thumbnail/id. Um dá suporte a GET e o outro dá suporte a POST:
public class ProductsController : ApiController
{
[HttpGet]
[ActionName("Thumbnail")]
public HttpResponseMessage GetThumbnailImage(int id);
[HttpPost]
[ActionName("Thumbnail")]
public void AddThumbnailImage(int id);
}
Não Ações
Para impedir que um método seja invocado como uma ação, use o [NonAction]
atributo . Isso sinaliza para a estrutura que o método não é uma ação, mesmo que ele corresponda às regras de roteamento de outra forma.
// Not an action method.
[NonAction]
public string GetPrivateData() { ... }
Leitura Adicional
Este tópico forneceu uma exibição de alto nível do roteamento. Para obter mais detalhes, consulte Seleção de Roteamento e Ação, que descreve exatamente como a estrutura corresponde um URI a uma rota, seleciona um controlador e, em seguida, seleciona a ação a ser invocada.