[水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute

时间:2022-08-07 16:27:04

问题

在 Controller 中有一个 public 的方法,但是又不想将这个 publlic 方法暴露成为一个 API。

解决方案

ASP.NET Web API 中,正常是通过 HTTP 谓词来匹配 Controller 中相关 Action 的。默认情况下,Contoller 中的每个 public 方法都是一个 Action。为了防止 public 的方法成为 Action,只要在 public 的方法上使用 [NonAction] 属性就可以。

工作原理

NoActionAttribute(如代码片段 3-19 所示)是一个非操作类,其中没有做任何事情,只是一个标记。

代码片段 3-19. NonAction 定义

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class NonActionAttribute : Attribute
{
}

ApiControllerActionSeletor,在 Controller 找到合适的 Action 时,内部的验证执行如代码片段 3-10 所示,他将 Controller 中所有的 public 方法都作为潜在的 Action,然后再进行逐步筛选,声明再 ApiController 的会被排除掉,声明再 IHttpController 也会被排除掉,最后,如果使用了 NonActionAttribute 的也会被排除掉。

代码片段 3-20 ApiControllerActionSelector 针对 Action 的过滤规则

[水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute

注意 这段验证逻辑是在 ApiControllerAtionSelector 内部的,如果自己代码中继承并实现了 IHttpActionSelector,要保证自己的实现中有类似逻辑的代码,才能保证 NonActionAttribute 工作正常。

在 ReflectHttpActionDescriptor 类中 ASP.NET WEB API 会包装每一个 Action,此外,他还负责找出 Action 应该处理 Http 的请求类型。他是通过方法名字或者在方法上使用了相关属性(HttpGetAttribute,HttpPostAttribute,等等)。如果 Action 的名字是以 HTTP 动词(GET,POST,PUT,DELETE)开头的,ASP.NET WEB API 也会认为这 Action 适合处理相关 HTTP 类型的请求。

另外,Action 方法如果任何相关前缀或者声明属性都没有,ASP.NET WEB API 会默认他只能处理 POST 请求。这个是一个很红要,也很容易被忽略的地方。很多初学者会认为,什么前缀或者属性声明也没有,那么,客户端就不可能请求到这个 Action。

代码演示

代码片段 3-21 展示了三个 Action 方法。

  1. 处理 ASP.NET WEB API Get 请求。
  2. 处理 ASP.NET WEB API Post 请求(因为不使用任何 Http 谓词的话,默认是 Post 请求)。
  3. 使用了 NonActionAttribute 来告诉 ASP.NET WEB API,这个 Controller 中的 public 方法不是 Action。

代码片段 3-21. NonActionAttribute 例子

[水煮 ASP.NET Web API2 方法论](3-7)默认 Action 请求方式以及 NonActionAttribute