Маршрутизация Web API с несколькими параметрами
Я пытаюсь выяснить, как сделать маршрутизацию для следующих веб-API контроллера:
public class MyController : ApiController
{
// POST api/MyController/GetAllRows/userName/tableName
[HttpPost]
public List<MyRows> GetAllRows(string userName, string tableName)
{
...
}
// POST api/MyController/GetRowsOfType/userName/tableName/rowType
[HttpPost]
public List<MyRows> GetRowsOfType(string userName, string tableName, string rowType)
{
...
}
}
на данный момент я использую этот маршрут для URLs:
routes.MapHttpRoute("AllRows", "api/{controller}/{action}/{userName}/{tableName}",
new
{
userName= UrlParameter.Optional,
tableName = UrlParameter.Optional
});
routes.MapHttpRoute("RowsByType", "api/{controller}/{action}/{userName}/{tableName}/{rowType}",
new
{
userName= UrlParameter.Optional,
tableName = UrlParameter.Optional,
rowType= UrlParameter.Optional
});
но на данный момент работает только первый метод (с 2 параметрами). Я на правильных линиях, или я получил формат URL или маршрутизацию совершенно неправильно? Маршрутизация кажется мне черной магией...
2 ответов
проблема в вашем api/MyController/GetRowsOfType/userName/tableName/rowType
URL всегда будет соответствовать первому маршруту, поэтому второй никогда не достигается.
простое исправление, зарегистрируйте свой RowsByType
путь первый.
Я видел WebApiConfig get"из-под контроля" С сотни маршрутов помещен в нем.
вместо этого я лично предпочитаю Маршрут
Вы путаете его с POST и GET
[HttpPost]
public List<MyRows> GetAllRows(string userName, string tableName)
{
...
}
протоколы HttpPost и GetAllRows ?
почему бы вместо этого не сделать это:
[Route("GetAllRows/{user}/{table}")]
public List<MyRows> GetAllRows(string userName, string tableName)
{
...
}
или измените на маршрут ("PostAllRows" и PostRows я думаю, что вы действительно делаете запрос GET, поэтому код, который я показываю, должен работать для вас. Ваш вызов от клиента будет тем , что находится в маршруте, поэтому он найдет ваш метод с GetAllRows , но сам метод, это имя может быть любым, что вы хотите, так что пока вызывающий абонент соответствует URL-адресу в маршруте, вы можете поместить GetMyStuff для метода, если вы действительно хотите.
обновление:
Я на самом деле предпочитаю быть explicit
С типом HTTP methods
И я предпочитаю сопоставлять параметры маршрута с методом params
[HttpPost]
[Route("api/lead/{vendorNumber}/{recordLocator}")]
public IHttpActionResult GetLead(string vendorNumber, string recordLocator)
{ .... }
(маршрут lead
не нужно соответствовать имени метода GetLead
но вы захотите сохранить те же имена на парах маршрута и парамах метода, даже если вы можете изменить порядок , например, поставить recordLocator перед vendorNumber, даже если маршрут противоположен - я этого не делаю, так как зачем делать его более запутанным).
бонус: Теперь ты всегда можно использовать regex в маршрутах, например
[Route("api/utilities/{vendorId:int}/{utilityType:regex(^(?i)(Gas)|(Electric)$)}/{accountType:regex(^(?i)(Residential)|(Business)$)}")]
public IHttpActionResult GetUtilityList(int vendorId, string utilityType, string accountType)
{