2014-01-15 25 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) 
    { 
     ... 
    } 
} 

目前,我正在使用此路由的网址:

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

怎样一个指定的参数是不可选?我希望第一个是必需的,第二个是可选的? – Zapnologica

+0

路由只是更加痛苦的IMO在webapiconfig中做它,看到我的路由属性路由回答 –

回答

12

问题是您的api/MyController/GetRowsOfType/userName/tableName/rowType URL始终会匹配第一条路由,所以第二条路径永远不会到达。

简单修复,首先注册您的RowsByType路线。

34

我所见过的WebApiConfig GET“失控”数百名放置在其路由的。

相反,我个人比较喜欢Attribute Routing

你正在创造一种混乱与POST和GET

[HttpPost] 
public List<MyRows> GetAllRows(string userName, string tableName) 
{ 
    ... 
} 

HttpPostGetAllRows

为什么不能代替做到这一点:

[Route("GetAllRows/{user}/{table}")] 
public List<MyRows> GetAllRows(string userName, string tableName) 
{ 
    ... 
} 

或更改路线(“PostAllRows”和PostRows我认为你是真正做一个GET请求,所以我表现应该为你工作的代码你来自客户端的呼叫将是WHATEVER在ROUTE中,因此它将使用GetAllRows来查找您的METHOD,但该方法本身,名称可以是任何您想要的,因此只要呼叫者在ROUTE中匹配URL,您就可以将GetMyStuff方法,如果你真的想。

更新:

其实我更愿意explicit类型的HTTP methods ,我更喜欢以匹配路线PARAMS的方法PARAMS

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

(路线lead并不需要匹配方法名GetLead但是,你会想要在路径参数和方法参数上保留相同的名称,即使您可以更改顺序,例如在vendorNumber之前放置recordLocator,即使路由是相反的 - 我不这样做,为什么让它看起来更混乱)。

奖励: 现在,你可以随时使用正则表达式的航线,以及,例如

[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/ –