具有多个参数的Web API路由

时间:2014-01-15 14:39:03

标签: c# asp.net-web-api asp.net-web-api-routing

我正在尝试研究如何为以下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 个答案:

答案 0 :(得分:50)

我已经看到 WebApiConfig 得到&#34; 失控&#34; ,其中放置了数百条路线

相反,我个人更喜欢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)
{
   ...
}

或更改为Route(&#34; PostAllRows&#34;和PostRows)我认为您确实正在执行GET请求,因此我显示的代码应该适合您。来自客户端的调用将在ROUTE中为WHATEVER,因此它会使用GetAllRows找到你的方法,但方法本身,名称可以是你想要的任何东西,所以只要调用者匹配ROUTE中的URL,如果你真的想要,你可以为该方法输入GetMyStuff。 / p>

<强>更新

我实际上更喜欢explicit类型HTTP methods 我更喜欢将路线参数与方法参数匹配

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

(路由lead不需要匹配方法名称GetLead,但是您希望在路径参数和方法参数上保留相同的名称,即使您可以更改顺序,例如put在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)
    {

答案 1 :(得分:15)

问题是您的api/MyController/GetRowsOfType/userName/tableName/rowType网址将始终与第一条路线匹配,因此永远不会达到第二条路线。

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