對於到多數開發者,都會忽略或者不知道 Action 沒有任何 HTTP 的聲明屬性,Web Api 怎樣處理? 對於初學者,還是需要瞭解 NonActionAttribute ...
問題
在 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 的過濾規則
註意 這段驗證邏輯是在 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 方法。
- 處理 ASP.NET WEB API Get 請求。
- 處理 ASP.NET WEB API Post 請求(因為不使用任何 Http 謂詞的話,預設是 Post 請求)。
- 使用了 NonActionAttribute 來告訴 ASP.NET WEB API,這個 Controller 中的 public 方法不是 Action。
代碼片段 3-21. NonActionAttribute 例子