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
中的 UseEndpoints
、UseMvc 或 UseMvcWithDefaultRoute 定義的傳統路由訪問操作。
自動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]
不適用於具有特殊含義的任何複雜的內置類型,如 IFormCollection 和 CancellationToken。 綁定源推理代碼將忽略這些特殊類型。[FromForm]
針對 IFormFile 和 IFormFileCollection 類型的操作參數進行推斷。 該特性不針對任何簡單類型或用戶定義類型進行推斷。[FromRoute]
針對與路由模板中的參數相匹配的任何操作參數名稱進行推斷。 當多個路由與一個操作參數匹配時,任何路由值都視爲[FromRoute]
。[FromQuery]
針對任何其他操作參數進行推斷。
FromBody 推理說明
對於簡單類型(例如 string
或 int
),推斷不出 [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/json
和 application/xml
。
使用 [Consumes] 屬性,操作可以限制支持的請求內容類型。 將 [Consumes]
屬性應用於操作或控制器,同時指定一個或多個內容類型:
[HttpPost]
[Consumes("application/xml")]
public IActionResult CreateProduct(Product product)
在上面的代碼中,CreateProduct
操作指定內容類型 application/xml
。 路由到此操作的請求必須指定 application/xml
的 Content-Type
頭。 如果請求未指定 application/xml
的 Content-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 的請求。 控制器的兩個操作(PostJson
和 PostForm
)都使用相同的 URL 處理 POST 請求。 如果 [Consumes]
屬性不應用類型約束,則會拋出不明確匹配異常。
[Consumes]
屬性應用於兩個操作。 PostJson
操作處理使用 application/json
的 Content-Type
頭髮送的請求。 PostForm
操作處理使用 application/x-www-form-urlencoded
的 Content-Type
頭髮送的請求。