我正在查看Microsoft的以下教程。根据本教程,
在第一个示例中,“products”与名为的控制器匹配 ProductsController的。请求是GET请求,因此框架 在名称以...开头的ProductsController上查找方法 “得到...”。此外,URI不包含可选的{id} segment,所以框架查找没有参数的方法。该 ProductsController :: GetAllProducts方法满足所有这些 要求。
如果有两种方法,如GetAllProducts()和GetSoldProducts(),会发生什么?两者都没有参数。
答案 0 :(得分:12)
这个特定问题有两种可能的解决方案:
更改MapHttpRoute调用以指定操作的名称。 (我正在使用自托管语法):
config.Routes.MapHttpRoute(
"API Route 1",
"api/{controller}/{action}");
config.Routes.MapHttpRoute(
"API Route 2",
"api/{action}",
new { controller = "products" });
所以你的http客户端会调用:
api/products/GetAllProducts
或api/GetAllProducts
api/products/GetSoldProducts
或api/GetSoldProducts
请参阅: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api
将每个方法放在一个单独的控制器(ProductsController,SoldProductsController)中。因此,您可以致电api/products
和api/soldproducts
来获取结果。
相关主题...如果您有多个具有相同类型的单个基本参数的Get操作,ASP.NET Web API将查看参数的名称以解析要调用的重载操作。
例如,如果您有两个操作:
GetProductByName(string name)
GetProductByCategory(string category)
您的http客户端可以调用
api/products?name=hammer
api/products?category=toys
并且路由引擎将调用正确的操作。
答案 1 :(得分:8)
假设您正在使用默认路由,简短答案是:将调用您的类首先定义的方法(在顶部)。另一种方法无法访问。
注意:测试版表现为“匹配多种方法” - RC&发布版本有点强迫症。如果存在多个潜在匹配,则会引发错误。此更改消除了多个模糊匹配的混淆。同时,它降低了我们在同一个控制器中混合REST和RPC样式接口的能力,依赖于顺序&重叠的路线。
从another post I wrote on the topic轻松偷窃:
WebAPI匹配语义
WebAPI使用的匹配语义非常简单。
因此,在您的代码示例中,没有参数的GET请求与没有参数的Get*( )
函数匹配。 Get包含和ID查找Get***(int id)
。
<强>实施例强>
虽然匹配的语义很简单,但它给MVC开发人员(至少是这个开发人员)造成了一些困惑。让我们看一些例子:
奇数名称 - 您的get方法可以命名为任何名称,只要它以“get”开头即可。因此,对于窗口小部件控制器,您可以将函数命名为GetStrawberry()
,它仍将匹配。将匹配视为:methodname.StartsWith("Get")
多重匹配方法 - 如果您有两个没有参数的Get方法会怎样? GetStrawberry()
和GetOrange()
。我可以告诉你,代码中首先定义的函数(文件顶部)赢得了...奇怪。这会产生副作用,使控制器中的某些方法无法访问(至少使用默认路由)....陌生人。
<强>更新强>
@WinFXGuy - 发表评论有点长,但是......
不要妄下结论!我试着回答你提出的问题,但这只是故事的一半。您可以做很多事情来更改默认行为。
首先,WebAPI支持大部分oData规范。如果将IQueryable
冒泡到控制器,oData参数将自动与查询对象集成。它采用$filter
,$top
和$skip
等参数。因此,在您的情况下,您可以编写一种方法并传递类似$filter=sale_date neq null
的内容。
此外,您可以应用[ResultLimit]
属性来阻止人们询问150亿条记录。
第二您可以修改路线。默认路由的目标是RESTful api,每个实体通常有1个控制器。您可以更改路由并使其成为RPC样式。
如果您查看我的链接帖子,我会解释如何保留默认路由绑定,添加“子文件夹”,并允许在我需要GetAllProducts()
和GetSoldProducts()
的情况下进行其他方法调用。
答案 2 :(得分:4)
添加答案以反映最新版本的Web API本身支持[Route]
属性
[Route("api/products")]
public IEnumerable<Product> GetAllProducts(){}
[Route("api/products/sold")]
public IEnumerable<Product> GetSoldProducts(){}