14

我为我的Customer模型制作了一个 Web API 类。我有标准方法(GET、POST、PUT、DELETE)。问题是,我想实现另一种 GET 方法,即搜索。像这样的东西:

[HttpGet]
public IEnumerable<Customer> Search(string id)
{
    var customers = customerRepository.Search(id);
    return customers;
}

搜索方法使用该方法根据我的客户的帐号执行搜索.Contains()

问题是,当我导航到:mySite.com/api/Customers/Search/123我得到一个 404。我在这里做错了什么?

4

2 回答 2

50

虽然 Darin 的答案总是质量上乘,但这个问题实际上会受益于解释如何在任何 API 中实际完成搜索、分页和过滤以及如何使用最新版本的 Web API (v2) 完成的答案。

这是一篇我认为关于此事的好资源(技术独立)的帖子:http: //www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api

答案还应该反映 ASP.NET Web API v2 中的新功能,因为 Darin 的答案已经很老了。

由于在谷歌搜索“asp.net web api search”时这个问题出现在顶部,我将在这里尝试解释一些事情。

要使用最新版本的 ASP.NET Web API (v2) 尽可能接近 REST 原则,应该认真研究最新版本中引入的属性路由。使用旧的、经典的、基于约定的路由(在 global.asax.cs 或 RouteConfig.cs 中)很难实现 RESTful 路由。

你应该在这里阅读更多关于 http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

现在,详细介绍如何实施您询问的细节。

最常见的做法是通过查询字符串参数公开这些类型的功能。

例如,根据 REST 原则,您的客户资源应该有一个端点

/api/customers

要实现这一点,您将像这样在 Web API 控制器中装饰您的 GetCustomers() 操作

[HttpGet]
[Route("/api/customers")]
public HttpResponseMessage GetCustomers(string q="", string sortBy="", string sortDirection="", bool active=true, ...)
{ 
// q = being optional search query
// sortBy = optional sort by column/property
// sortDirection = optional sort direction
// active = filter on 'active' column/property
// ... other filters may be applicable
}

如果您想提供过滤的视图,您将非常接近您在经典 MVC 中所做的操作来实现此操作。

如果真的需要,我只会在一些自定义边缘情况下引入新的控制器和自定义操作。

关于 SearchFilter 强类型对象的评论,让我们解释一下这不会开箱即用,因为默认模型绑定器在使用 GET 请求时不会绑定到此类。

因此,我要么将这些属性从 SearchFilter 类中取出并将它们放在操作本身上,以便它们通过查询字符串绑定器绑定,或者[FromBody]如果您想从请求正文绑定,则使用绑定器。根据http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api

高温高压

于 2014-01-21T13:26:58.670 回答
8

根据默认路由设置,仅允许使用标准控制器操作名称(RESTful 和调度是基于 HTTP 动词完成的)。如果您想违反 RESTful 约定并使用一些自定义操作名称,那么您必须修改您的路由设置,以便在 url: 中包含操作名称api/{controller}/{action}/{id}。现在您可以发送一个请求,/api/Customers/Search/123该请求将调用客户 API 控制器上的搜索操作。

于 2012-07-25T10:56:20.300 回答