控制器动作命名规范

11

根据命名约定,WebApi控制器的动作名称应为Get()、Put()、Post()等。但是,如果我有一个名为CustomerController的控制器,现在我想要在其中拥有两个操作。一个是GetCustomerById(int id),另一个是GetCustomerByAge(int age)。在这里,这两个操作都接受一个int类型的参数。

所以,如果我想使URL用户友好化,例如"api/customer/",并且我想遵循只使用Get(int id)/Get(int age)的操作命名约定,我该怎么做?


你正在使用哪个Web Api版本?如果你正在使用Web Api 2,那么你可以使用Route属性。 - Usman Khalid
4个回答

5
如果想让Web Api在路由时查找动作名称,需要将App_Start文件夹中的WebApiConfig.cs类更改为以下内容:
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

然后您只需向其发出GET请求:

http://mysite/api/customer/GetCustomerById/1

我建议您阅读下面的文章以深入了解:

使用操作名称进行路由


14
这个答案有误导性,REST应该在路径中使用名词,在HTTP方法中使用动词,例如 GET /api/customers/1。更多细节请参考:https://martinfowler.com/articles/richardsonMaturityModel.html。 - Vitaliy Ulantikov

5

Restful服务应该在URI中不包含CRUD函数名称(https://restfulapi.net/resource-naming/)

这样更加合适:

按ID获取 - http://mysite/api/customers/123

按年龄获取 - http://mysite/api/customers?age=21


在C# Web服务方法中实现多态并不容易。 - Antonio Rodríguez

3

另一种方法是使用HTTP方法属性。

除了使用HTTP方法的命名约定外,您还可以通过对操作方法进行装饰,明确指定操作的HTTP方法来执行操作,包括HttpGet、HttpPut、HttpPost或HttpDelete属性。

在以下示例中,FindProduct方法被映射到GET请求:

public class ProductsController : ApiController
{
    [HttpGet]
    public Product FindProduct(id) {}
}

为了允许一个操作使用多个HTTP方法,或者允许使用除GET、PUT、POST和DELETE之外的HTTP方法,请使用AcceptVerbs属性,并提供一个HTTP方法列表。

public class ProductsController : ApiController
{
    [AcceptVerbs("GET", "HEAD")]
    public Product FindProduct(id) { }
}

2
这是一个情况,严格遵循标准可能并不能帮助你太多。
一种解决方案是允许自己偏离REST风格。
你可以有两个获取方法:
一个可以是GetByID,另一个可以是GetByAge。
你的路由可能如下所示:
api/customer/getbyage/20 api/customer/getbyid/1134
这不完全符合REST,但足够接近,一个例外不会破坏任何东西。
我的观点是使用任何实现方式来帮助你的产品变得更加合理,不要过于担心标准。

您可以通过使用"/api/customers/1234"来维护正确的REST,该标识符将继续指示实际资源,同时使用"/api/customers?age=20",根据其他属性查找资源。 - David
1
我同意这个答案。有时候惯例很令人疲倦。 - Vanity Slug
我也同意,规则对于标准行为非常有用。但是如果你有一种非标准的行为,它不应该成为放弃规则路径的决定性因素。 - Niels Lucas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接