1. 程式人生 > WINDOWS開發 >【譯】ASP.NET Core Web APIs(三):使用ASP.NET Core建立Web APIs 【下篇】

【譯】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的結果。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/jsonapplication/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 傳送的請求。

額外資源