【譯】ASP.NET Core Web APIs(三):使用ASP.NET Core建立Web APIs 【下篇】
Multipart/form-data 請求推斷
當一個Action方法的引數被標記為[FromForm]特性時,[ApiController]特性會應用一個推斷規則,此時,請求Content-Type被推斷為multipart/form-data。
為了禁用預設的行為,在Startup.ConfigureServices中將SuppressConsumesConstraintForFormFileParameters設定為true。
services.AddControllers() .ConfigureApiBehaviorOptions(options => { options.SuppressConsumesConstraintForFormFileParameters= true; options.SuppressInferBindingSourcesForParameters = true; options.SuppressModelStateInvalidFilter = true; options.SuppressMapClientErrors = true; options.ClientErrorMapping[404].Link = "https://httpstatuses.com/404"; });
錯誤狀態程式碼的問題詳細
當相容性版本是2.2及以後,MVC會將一個錯誤結果(具有狀態碼400或者更改的結果)轉化為一個帶有ProblemDetails
是基於RFC 7807 specification,在一個HTTP響應中提供一個機器可讀的錯誤詳情。
考慮在一個控制器Action中的如下程式碼:
if (pet == null) { return NotFound(); }
NotFound方法產生一個具有ProblemDetails體的錯誤程式碼。比如:
{ type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",title: "Not Found",status: 404,traceId: "0HLHLV31KRN83:00000001}
禁用ProblemDetails響應
當SuppressMapClientErrors屬性被設定為true時,就會禁用為錯誤狀態程式碼自動建立ProblemDetails。在Startup.ConfigureServices中新增如下程式碼:
services.AddControllers .ConfigureApiBehaviorOptions(options => { options.SuppressConsumesConstraintForFormFileParameters = true; options.SuppressInferBindingSourcesForParameters = true; options.SuppressModelStateInvalidFilter = true; options.SuppressMapClientErrors = true; options.ClientErrorMapping[404].Link = "https://httpstatuses.com/404"; });
使用[Consumes]特性定義支援的請求上下文型別
預設情況下,一個Action支援所有可用的請求上下文型別。舉個例子,如果一個app被配置為支援JSON和XMLinput formatters,那麼這個Action便支援多種上下文型別,包括application/json
和application/xml。
[Cosumes]特性允許一個Action限制其支援的請求上下文型別。將[Cosume]應用到一個Action或者Controller上,指定一個或者多個上下文型別。
[HttpPost] [Consumes("application/xml")] public IActionResult CreateProduct(Product product)
在上述程式碼中,CreateProduct Action指定了上下文型別application/xml。路由到這個Action的請求必須指定一個
application/xml型別的Content-Type頭。沒有指定一個
application/xml型別的Content-Type頭的請求會導致一個415 Unsupported Media Type響應。
通過應用一個型別約束,[Cosumes]特性也允許一個Action基於即將來臨的請求上下文型別來影響它的選擇。考慮如下示例:
[ApiController] [Route("api/[controller]")] public class ConsumesController : ControllerBase { [HttpPost] [Consumes("application/json")] public IActionResult PostJson(IEnumerable<int> values) => Ok(new { Consumes = "application/json",Values = values }); [HttpPost] [Consumes("application/x-www-form-urlencoded")] public IActionResult PostForm([FromForm] IEnumerable<int> values) => Ok(new { Consumes = "application/x-www-form-urlencoded",Values = values }); }
在上述程式碼中,ConsumesController
被配置為處理髮送給這個URLhttps://localhost:5001/api/Consumes 的請求。這個控制器的兩個Action,PostJson
和 PostForm,會處理相同URL的POST請求。如果沒有[Cosumes]特性應用一個型別約束,將會丟擲一個不明確的匹配異常。
[Cosumes]特性被應用到兩個Action方法。PostJson會處理 以application/json Content-Type 傳送的請求。而PostForm會處理以application/x-www-form-urlencoded Content-Type 傳送的請求。
額外資源