2014-01-15 4 views
16

Я пытаюсь выяснить, как сделать маршрутизацию для следующего контроллера Web API:Web 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) 
    { 
     ... 
    } 
} 

На данный момент я использую этот маршрут для URL-адресов:

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 
        }); 

, но в настоящий момент работает только первый метод (с двумя параметрами). Я нахожусь на правильных строках, или я получил неправильный формат URL или маршрутизацию? Маршрутизация кажется черной магией для меня ...

+2

как можно указать параметр, который не является факультативным? Я хочу, чтобы первый был необходим, а второй - как дополнительный? – Zapnologica

+0

Маршрутизация просто более болезненна, ИМО делает это в webapiconfig, см. Мой ответ на маршрутизацию атрибутов с помощью маршрута –

ответ

12

Проблема заключается в том, что ваш адрес api/MyController/GetRowsOfType/userName/tableName/rowType всегда будет соответствовать первому маршруту, поэтому второй никогда не будет достигнут.

Простая установка, сначала зарегистрируйте свой RowsByType маршрут.

34

Я видел WebApiConfig прибудете «из-под контроля» с сотни маршрутов, расположенных в нем.

Вместо этого я лично предпочитаю Attribute Routing

Вы делаете его в заблуждение с 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 так кода я показываю должен работать для вас Ваш вызов от клиента будет WHATEVER находится в ROUTE, поэтому он НАЙТИ ваш МЕТОД с GetAllRows, но сам метод, это имя МОЖЕТ БЫТЬ все, что вы хотите, до тех пор, пока вызывающий абонент соответствует URL-адресу в ROUTE, вы можете ввести GetMyStuff для метода, если вы действительно хотели.

Обновление:

Я предпочитаю быть explicit с типом HTTP methods И я предпочитаю, чтобы соответствовать маршрут Params к методу PARAMS

[HttpPost] 
[Route("api/lead/{vendorNumber}/{recordLocator}")] 
public IHttpActionResult GetLead(string vendorNumber, string recordLocator) 
{ .... } 

(маршрут lead не нужно соответствовать имени метода GetLead но вы будете хотите сохранить одинаковые имена в параметрах маршрута и параметрах метода, даже если вы можете изменить порядок, например поместите recordLocator перед номером vendorNumber, даже если маршрут будет обратным - я этого не делаю, потому что почему это более запутанно смотреть).

Бонус: Теперь вы всегда можете использовать регулярные выражения маршрутов, а также, пример

[Route("api/utilities/{vendorId:int}/{utilityType:regex(^(?i)(Gas)|(Electric)$)}/{accountType:regex(^(?i)(Residential)|(Business)$)}")] 
public IHttpActionResult GetUtilityList(int vendorId, string utilityType, string accountType) 
    { 
+3

Я думаю, что «Маршрутизация атрибутов» также является лучшим выбором. +1 – alternatiph

+0

Для этого требуется API 2, который не всегда является опцией. – Zoomzoom

+0

, вы можете использовать этот https://www.nuget.org/packages/AttributeRouting/ –

Смежные вопросы