具有多个参数的 Web API 路由
Posted
技术标签:
【中文标题】具有多个参数的 Web API 路由【英文标题】:Web API routing with multiple parameters 【发布时间】:2014-02-04 02:12:43 【问题描述】:我正在研究如何为以下 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
);
但目前只有第一种方法(带有 2 个参数)有效。我是在正确的路线上,还是我的 URL 格式或路由完全错误?路由对我来说似乎是黑魔法......
【问题讨论】:
如何指定一个非可选参数?我希望第一个是必需的,第二个是可选的? 路由只是 IMO 在 webapiconfig 中做的更痛苦,请参阅我对 Route 属性路由的回答 【参考方案1】:我已经看到 WebApiConfig 变得“失控”,其中放置了数百条路由。
我个人更喜欢Attribute Routing
你把它与 POST 和 GET 混淆了
[HttpPost]
public List<MyRows> GetAllRows(string userName, string tableName)
...
HttpPost AND GetAllRows ?
为什么不这样做:
[Route("GetAllRows/user/table")]
public List<MyRows> GetAllRows(string userName, string tableName)
...
或更改为 Route("PostAllRows" 和 PostRows 我认为您确实在执行 GET 请求,因此我显示的代码应该适合您。您来自客户端的调用将是 ROUTE 中的任何内容,因此它会找到您的METHOD 与 GetAllRows,但方法本身,该名称可以是您想要的任何名称,因此只要调用者与 ROUTE 中的 URL 匹配,如果您真的需要,您可以为该方法输入 GetMyStuff。
更新:
我实际上更喜欢explicit
类型为HTTP methods
而且我更喜欢将路由参数与方法参数匹配
[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)
【讨论】:
我认为Attribute Routing
也是更好的选择。 +1
这需要 API 2,但这并不总是一种选择。
同样的建议适用于 asp.net 核心(没有尝试正则表达式),但如果我做了 [Route("~the/things/thingId/subthing id/save")]/ 和 [Route("~the/things/thingId/subthingid/submit")]/【参考方案2】:
问题是您的api/MyController/GetRowsOfType/userName/tableName/rowType
URL 将始终与第一个路由匹配,因此永远无法到达第二个路由。
简单修复,首先注册您的RowsByType
路由。
【讨论】:
以上是关于具有多个参数的 Web API 路由的主要内容,如果未能解决你的问题,请参考以下文章
无法使用具有多个参数的 MVC Web Api HttpPost 修饰操作