一文帶你Asp.Net webapi快速進階【詳細說明+使用案例】

webapi

就是使用asp.net core使用c#創建Restful服務,就是webapi,如果要使用webapi控制器

webapi中的控制器是派生自ControllerBase的類,

ControllerBase類

不要通過從 Controller 類派生來創建 Web API 控制器。 Controller 派生自 ControllerBase,並添加對視圖的支持,因此它用於處理 Web 頁面,而不是 Web API 請求。 此規則有一個例外:如果打算爲視圖和 Web API 使用相同的控制器,則從 Controller 派生控制器。

ControllerBase 類提供了很多用於處理 HTTP 請求的屬性和方法。

例如,ControllerBase.CreatedAtAction 返回 201 狀態代碼:

下面是 ControllerBase 提供的方法的更多示例。

方法 說明
BadRequest 返回 400 狀態代碼。
NotFound 返回 404 狀態代碼。
PhysicalFile 返回文件。
TryUpdateModelAsync 調用模型綁定
TryValidateModel 調用模型驗證

特性

Microsoft.AspNetCore.Mvc 命名空間提供可用於配置 Web API 控制器的行爲和操作方法的屬性。 下述示例使用屬性來指定受支持的 HTTP 操作動作和所有可返回的已知 HTTP 狀態代碼:

[HttpPost][ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult Create(Pet pet)
{
pet.Id = _petsInMemoryStore.Any() ?
_petsInMemoryStore.Max(p => p.Id) + 1 : 1;
_petsInMemoryStore.Add(pet);
return CreatedAtAction(nameof(GetById), new { id = pet.Id }, pet);
}

特性 說明
[[Route\]] 指定控制器或操作的 URL 模式。
[[Bind\]] 指定要包含的前綴和屬性,以進行模型綁定。
[[HttpGet\]] 標識支持 HTTP GET 操作謂詞的操作。
[[Consumes\]] 指定某個操作接受的數據類型。
[[Produces\]] 指定某個操作返回的數據類型。

ApiController特性

特定控制器上特性

[[ApiController\]]屬性可應用於控制器類,以啓用下述 API 特定的固定行爲:

必須有兼容性版本 2.2 或更高版本,才能使用“錯誤狀態代碼的問題詳細信息” 功能。 必須有兼容性版本 2.1 或更高版本,才能使用其他功能。

多個控制器上的特性

在多個控制器上使用該屬性的一種方法是創建通過 [ApiController] 屬性批註的自定義基控制器類。 下述示例展示了自定義基類以及從其派生的控制器:

[ApiController]
public class MyControllerBase : ControllerBase
{
}
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase

程序集上特性

如果將兼容性版本設置爲 2.2 或更高版本,則 [ApiController] 屬性可應用於程序集。 以這種方式進行註釋,會將 web API 行爲應用到程序集中的所有控制器。 無法針對單個控制器執行選擇退出操作。 將程序集級別的屬性應用於 Startup 類兩側的命名空間聲明:

[assembly: ApiController]
namespace WebApiSample
{
    public class Startup
    {
        ...
    }
}

特性路由要求

[ApiController] 屬性使屬性路由成爲要求。 例如:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase

不能通過由 Startup.Configure 中的 UseEndpointsUseMvcUseMvcWithDefaultRoute 定義的傳統路由訪問操作。

自動http 400響應

[ApiController] 屬性使模型驗證錯誤自動觸發 HTTP 400 響應。 因此,操作方法中不需要以下代碼:

if (!ModelState.IsValid)
{
    return BadRequest(ModelState);
}

ASP.NET Core MVC 使用 ModelStateInvalidFilter 操作篩選器來執行上述檢查。

默認 BadRequest 響應

使用 2.1 的兼容性版本時,HTTP 400 響應的默認響應類型爲 SerializableError。 下述請求正文是序列化類型的示例:

JSON

{
  "": [
    "A non-empty request body is required."
  ]
}

使用 2.2 或更高版本的兼容性版本時,HTTP 400 響應的默認響應類型爲 ValidationProblemDetails。 下述請求正文是序列化類型的示例:

JSON

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "|7fb5e16a-4c8f23bbfc974667.",
  "errors": {
    "": [
      "A non-empty request body is required."
    ]
  }
}

ValidationProblemDetails 類型:

  • 提供計算機可讀的格式來指定 Web API 響應中的錯誤。
  • 符合 RFC 7807 規範

記錄自動 400 響應

請參閱如何對模型驗證錯誤記錄自動 400 響應 (aspnet/AspNetCore.Docs #12157)

禁用自動 400 響應

若要禁用自動 400 行爲,請將 SuppressModelStateInvalidFilter 屬性設置爲 true。 將以下突出顯示的代碼添加到 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";
    });

綁定源參數推理

綁定源特性定義可找到操作參數值的位置。 存在以下綁定源特性:

特性 綁定源
[[FromBody\]] 請求正文
[[FromForm\]] 請求正文中的表單數據
[[FromHeader\]] 請求標頭
[[FromQuery\]] 請求查詢字符串參數
[[FromRoute\]] 當前請求中的路由數據
[[FromServices\]] 作爲操作參數插入的請求服務

如果沒有 [ApiController] 屬性或諸如 [FromQuery] 的綁定源屬性,ASP.NET Core 運行時會嘗試使用複雜對象模型綁定器。 複雜對象模型綁定器按已定義順序從值提供程序拉取數據。

在下面的示例中,[FromQuery] 特性指示 discontinuedOnly 參數值在請求 URL 的查詢字符串中提供:

[HttpGet]
public ActionResult<List<Product>> Get(
    [FromQuery] bool discontinuedOnly = false)
{
    List<Product> products = null;

    if (discontinuedOnly)
    {
        products = _productsInMemoryStore.Where(p => p.IsDiscontinued).ToList();
    }
    else
    {
        products = _productsInMemoryStore;
    }

    return products;
}

[ApiController] 屬性將推理規則應用於操作參數的默認數據源。 藉助這些規則,無需通過將屬性應用於操作參數來手動識別綁定源。 綁定源推理規則的行爲如下:

  • [FromBody] 針對複雜類型參數進行推斷。 [FromBody] 不適用於具有特殊含義的任何複雜的內置類型,如 IFormCollectionCancellationToken。 綁定源推理代碼將忽略這些特殊類型。
  • [FromForm] 針對 IFormFileIFormFileCollection 類型的操作參數進行推斷。 該特性不針對任何簡單類型或用戶定義類型進行推斷。
  • [FromRoute] 針對與路由模板中的參數相匹配的任何操作參數名稱進行推斷。 當多個路由與一個操作參數匹配時,任何路由值都視爲 [FromRoute]
  • [FromQuery] 針對任何其他操作參數進行推斷。

FromBody 推理說明

對於簡單類型(例如 stringint),推斷不出 [FromBody]。 因此,如果需要該功能,對於簡單類型,應使用 [FromBody] 屬性。

當操作擁有多個從請求正文中綁定的參數時,將會引發異常。 例如,以下所有操作方法簽名都會導致異常:

  • [FromBody] 對兩者進行推斷,因爲它們是複雜類型。

    [HttpPost]
    public IActionResult Action1(Product product, Order order)
    
  • [FromBody] 對一個進行歸屬,對另一個進行推斷,因爲它是複雜類型。

    [HttpPost]
    public IActionResult Action2(Product product, [FromBody] Order order)
    
  • [FromBody] 對兩者進行歸屬。

    [HttpPost]
    public IActionResult Action3([FromBody] Product product, [FromBody] Order o
    

禁用推理規則

若要禁用綁定源推理,請將 SuppressInferBindingSourcesForParameters 設置爲 true。在 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";
    });

Multipart/form-data 請求推理

使用 [FromForm\] 屬性批註操作參數時,[ApiController] 屬性應用推理規則。 將推斷 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";
    });

錯誤狀態代碼的問題詳細信息

禁用 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] 屬性定義支持的請求內容類型

默認情況下,操作支持所有可用的請求內容類型。 例如,如果應用配置爲同時支持 JSON 和 XML 輸入格式化程序,那麼操作支持多種內容類型,其中包括 application/jsonapplication/xml

使用 [Consumes] 屬性,操作可以限制支持的請求內容類型。 將 [Consumes] 屬性應用於操作或控制器,同時指定一個或多個內容類型:

[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)

在上面的代碼中,CreateProduct 操作指定內容類型 application/xml。 路由到此操作的請求必須指定 application/xmlContent-Type 頭。 如果請求未指定 application/xmlContent-Type 頭,會生成 415 不支持的媒體類型響應。

使用 [Consumes] 屬性,操作可以通過應用類型約束,根據傳入請求的內容類型來影響它的選擇。 請看下面的示例:

[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 配置爲處理髮送到 https://localhost:5001/api/Consumes URL 的請求。 控制器的兩個操作(PostJsonPostForm)都使用相同的 URL 處理 POST 請求。 如果 [Consumes] 屬性不應用類型約束,則會拋出不明確匹配異常。

[Consumes] 屬性應用於兩個操作。 PostJson 操作處理使用 application/jsonContent-Type 頭髮送的請求。 PostForm 操作處理使用 application/x-www-form-urlencodedContent-Type 頭髮送的請求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章