講一下Asp.net core MVC2.1 裡面的 ApiContr
先貼文章
正文
ASP.NET Core MVC 2.1 特意為構建 HTTP API 提供了一些小特性,今天主角就是 ApiControllerAttribute
. (注:文章是18年2月份的,所以文章提到了core2.1還沒釋出)。
0. ApiControllerAttribute 繼承自 ControllerAttribute
ASP.NET Core MVC 已經有了ControllerAttribute,這個用來標註一個型別是否是Controller。標註了之後框架就知道哪些是系統裡面的Controller了。(框架也有其他方法來獲取程式裡面的Controller,所以,這個ControllerAttribute不是必須的)。
ApiControllerAttribute
是ControllerAttribute
的子類,所以,框架在處理Controller發現的時候和ControllerAttribute
標註的物件是一樣的。
但是,因為ApiControllerAttribute
實現了IApiBehaviorMetadata
介面,所以提供了一些額外的特這些特性是以HTTP Api為出發點的。下面介紹一下這些特性。
1. 自動模型狀態驗證
這個是重點,框架會幫你自動驗證model的state,也就是ModelState
.(注:不過我就是因為用FluentValidation的時候模型驗證不管用了出問題了才找到這篇文章的).
框架會為你自動註冊ModelStateInvalidFilter
,這個會執行在OnActionExecuting
事件裡面(具體來說:在action執行之前,model繫結之後)。他內部會檢查ModelState
是否為Valid,如果為InValid會直接返回400 BadRequest,這樣就沒有必要執行後面的程式碼,提高效率。
它會自動把model state 放到response裡面,content type 是application/problem+json
。當然你也可以自定義,因為畢竟你會有自己的驗證,後文會講。
下面,我們先來舉個例子說一下。
之前的寫法
[Route("[controller]")]public class BookController : Controller{ [HttpPost("")] public IActionResult PostBook([FromBody]Book book) { if (ModelState.IsValid) //判斷狀態 { return BadRequest(ModelState); } //其他程式碼。。。 } }
現在可以這麼寫
[ApiController] [Route("[controller]")]public class BookController : Controller{ [HttpPost("")] public IActionResult PostBook(Book book) { //直接寫,不用驗證modelstate } }
順道說一下,ModelStateInvalidFilter
是個公共類,所以,不用ApiControllerAttribute
也可以使用它。
2.引數繫結策略的自動推斷
另一個非常有用的特性是action裡面的引數的模型繫結可以自動推斷。
ASP.NET Core MVC裡面有一個比較令人惱怒的問題你需要手動給引數指定[FromBody]
這個特性,以便讓系統知道如何從Request body裡面反序列化他們,比如反序列化json。因此,寫了很多第三方的庫來解決這個問題,比如:
其他不寫了,,就舉個例子
現在,這些可以自動解決了。
除此之外,如果一個引數在route裡面定義了,他會自動從先從path,也就是url上嘗試繫結,不行的話會去從查詢引數上繫結。IFormFlie
預設從form表單上繫結獲取。
下面看程式碼:
之前
[Route("[controller]")]public class BookController : Controller{ [HttpPost("")] public IActionResult PostBook([FromBody]Book book) { // 寫程式碼 } }
現在
[ApiController] [Route("[controller]")]public class BookController : Controller{ [HttpPost("")] public IActionResult PostBook(Book book)//FromBody沒必要寫了 { // 寫程式碼 } }
3. 處理multipart/form-data
請求
如果你的action裡面的一個引數指定了[FromFile]
特性(這通常是用於檔案上傳的),框架會自動假設請求是multipart/form-data
。這個是用來解決社群裡面提的這個。
不過這個也是可選的,只要你自己定義在action上定義一下[Consumes(...)]
。
4.其他
有兩個注意點:
ApiExplorer 的可見性。 預設所有的controller對
ApiExplorer
都是可見的,所以,不影響swagger 等的生成。只是一個基於特性的路由。集中的路由機制不會應用在API controller,框架要求只能使用基於特性的路由,即在action上指定
[Route("XXX")]
的方式。
5. 行為自定義
像MVC框架的大部分元件一樣,ApiControllerAttribute
的行為是高度可自定義的。首先,上面說的大部分內容都是可以簡單的用 on/off 來切換。
具體的設定是在startup方法裡面透過ApiBehaviorOptions
來實現,先來看一下這個類。
public class ApiBehaviorOptions { public FuncInvalidModelStateResponseFactory { get; set; } public bool SuppressModelStateInvalidFilter { get; set; } public bool SuppressInferBindingSourcesForParameters { get; set; } public bool SuppressConsumesConstraintForFormFileParameters { get; set; } }
所有bool型別的屬性預設都是false。Suppres有阻止的意思。可以透過以下方法進行設定。
services.Configure(options => { options.SuppressModelStateInvalidFilter = true; options.SuppressConsumesConstraintForFormFileParameters = true; });
來看一下InvalidModelStateResponseFactory
屬性,他是一個返回IActionResult
的Func,透過他,我們可以注入自己的委託來實現需要的返回型別,舉個例子。
services.Configure(options => { options.InvalidModelStateResponseFactory = actionContext => { var errors = actionContext.ModelState .Where(e => e.Value.Errors.Count > 0) .Select(e => new Error { Name = e.Key, Message = e.Value.Errors.First().ErrorMessage }).ToArray(); return new BadRequestObjectResult(errors); } }); class Error{ public string Name { get; set; } public string Message { get; set; } }
原文出處:https://www.cnblogs.com/sheldon-lou/p/9495377.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2768/viewspace-2811910/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【asp.net core 系列】 1 帶你瞭解一下asp.net coreASP.NET
- Asp.net Core啟動流程講解(四)ASP.NET
- 【ASP.NET Core】體驗一下 Mini Web APIASP.NETWebAPI
- C# ASP.NET Core 中 IWebHostEnvironment 介面的作用是什麼?C#ASP.NETWeb
- ASP.NET Core ----ASP.NET Core中使用Code FirstASP.NET
- ASP.NET 6.0 Core 遷移 ASP.NET Core 7.0ASP.NET
- Asp.net core mvc裡面怎麼新增全域性的FilterASP.NETMVCFilter
- Go 裡面的 ^ 和 &^Go
- [續更]一起來擼一下Flex佈局裡面的那些屬性Flex
- ASP.NET Core: 全新的ASP.NET !ASP.NET
- 在ASP.NET Core中用HttpClient(六)——ASP.NET Core中使用HttpClientFactoryASP.NETHTTPclient
- 面試官:你給我說一下執行緒池裡面的幾個鎖吧。面試執行緒
- ASP.NET Core - 開篇ASP.NET
- asp.net core 整合JWTASP.NETJWT
- asp.net core 整合 PrometheusASP.NETPrometheus
- angular8裡面的*ngSwitchAngular
- 聊聊Go裡面的閉包Go
- 獲取cookie裡面的值Cookie
- $(function{})裡面的onclick報錯Function
- 遊戲裡面的容斥原理遊戲
- php 呼叫dll 裡面的方法PHP
- .NET Core 1.0、ASP.NET Core 1.0和EF Core 1.0簡介ASP.NET
- 【asp.net core 系列】14 .net core 中的IOCASP.NET
- ASP.Net Core5.0 EF Core使用記錄ASP.NET
- ASP.NET Core Web API 索引 (更新Redis in .NET Core)ASP.NETWebAPI索引Redis
- 父頁面如何輸出iframe裡面的變數,或者呼叫iframe裡面的方法?變數
- ASP.NET 5 已終結,迎來 ASP.NET Core 1.0 和 .NET Core 1.0ASP.NET
- ASP.NET core 2.2 截圖ASP.NET
- ASP.NET Core 配置檔案ASP.NET
- asp.net core 系列之StartupASP.NET
- 【ASP.NET Core】URL重寫ASP.NET
- 理解ASP.NET Core - [04] HostASP.NET
- 理解ASP.NET Core - [01] StartupASP.NET
- ASP.NET Core WebApi版本控制ASP.NETWebAPI
- asp.net core mvc 分頁ASP.NETMVC
- ASP.NET Core 啟動(1)ASP.NET
- ASP.NET Core - 入口檔案ASP.NET
- ASP.NET Core 過濾器ASP.NET過濾器