if (!ModelState.IsValid)
return BadRequest(ModelState);
ASP.NET Core MVC 使用 ModelStateInvalidFilter 操作筛选器来执行上述检查。
默认 BadRequest 响应
HTTP 400 响应的默认响应类型为 ValidationProblemDetails。 下述响应正文是序列化类型的示例:
"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 规范。
要使自动和自定义响应保持一致,请调用 ValidationProblem 方法,而不是 BadRequest。 ValidationProblem
返回 ValidationProblemDetails 对象以及自动响应。
记录自动 400 响应
若要记录自动 400 响应,请将 InvalidModelStateResponseFactory 委托属性设置为执行自定义处理。 默认情况下,InvalidModelStateResponseFactory
使用 ProblemDetailsFactory 创建 ValidationProblemDetails 实例。
以下示例演示如何检索 ILogger<TCategoryName> 实例以记录有关自动 400 响应的信息:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
var logger = context.HttpContext.RequestServices
.GetRequiredService<ILogger<Program>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails
// response.
// To produce a custom response, return a different implementation of
// IActionResult instead.
return builtInFactory(context);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
禁用自动 400 响应
若要禁用自动 400 行为,请将 SuppressModelStateInvalidFilter 属性设置为 true
。 添加以下突出显示的代码:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
绑定源参数推理
绑定源特性定义可找到操作参数值的位置。 存在以下绑定源特性:
当值可能包含 %2f
(即 /
)时,请勿使用 [FromRoute]
。 %2f
不会转换为 /
(非转义形式)。 如果值可能包含 %2f
,则使用 [FromQuery]
。
如果没有 [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();
products = _productsInMemoryStore;
return products;
[ApiController]
属性将推理规则应用于操作参数的默认数据源。 借助这些规则,无需通过将属性应用于操作参数来手动识别绑定源。 绑定源推理规则的行为如下:
[FromServices]
针对在 DI 容器中注册的复杂类型参数进行推断。
[FromBody]
针对未在 DI 容器中注册的复杂类型参数进行推断。 [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 order)
FromServices 推理说明
当类型配置为服务时,参数绑定通过依赖关系注入绑定参数。 这意味着不需要将 [FromServices]
属性显式应用到参数。 在以下代码中,这两个操作返回时间:
[Route("[controller]")]
[ApiController]
public class MyController : ControllerBase
public ActionResult GetWithAttribute([FromServices] IDateTime dateTime)
=> Ok(dateTime.Now);
[Route("noAttribute")]
public ActionResult Get(IDateTime dateTime) => Ok(dateTime.Now);
在极少数情况下,自动 DI 可能会中断 DI 中具有 API 控制器的操作方法中也接受的类型的应用。 在 DI 中拥有类型并作为 API 控制器操作中的参数并不常见。
若要为单个操作参数禁用 [FromServices]
推理,请将所需的绑定源属性应用于参数。 例如,将 [FromBody]
属性应用于应从请求正文绑定的操作参数。
若要全局禁用 [FromServices]
推理,请将 DisableImplicitFromServicesParameters 设置为 true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddSingleton<IDateTime, SystemDateTime>();
builder.Services.Configure<ApiBehaviorOptions>(options =>
options.DisableImplicitFromServicesParameters = true;
var app = builder.Build();
app.MapControllers();
app.Run();
类型将在应用启动时通过 IServiceProviderIsService 来检查,以确定 API 控制器操作中的参数是来自 DI 还是来自其他源。
用于推断 API 控制器操作参数绑定源的机制使用以下规则:
以前指定的 BindingInfo.BindingSource
永远不会被覆盖。
在 DI 容器中注册的复杂类型参数被分配 BindingSource.Services
。
在 DI 容器中未注册的复杂类型参数被分配 BindingSource.Body
。
具有在任何路由模板中显示为路由值的名称的参数被分配 BindingSource.Path
。
所有其他参数都是 BindingSource.Query
。
禁用推理规则
若要禁用绑定源推理,请将 SuppressInferBindingSourcesForParameters 设置为 true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
[ApiController]
属性对 IFormFile 和 IFormFileCollection 类型的操作参数应用推理规则。 为这些类型推断 multipart/form-data
请求内容类型。
要禁用默认行为,请将 SuppressConsumesConstraintForFormFileParameters 属性设置为 true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
错误状态代码的问题详细信息
MVC 将错误结果(状态代码为 400 或更高)转换为状态代码为 ProblemDetails 的结果。 ProblemDetails
类型基于 RFC 7807 规范,用于提供 HTTP 响应中计算机可读的错误详细信息。
考虑在控制器操作中使用以下代码:
if (pet == null)
return NotFound();
NotFound
方法会生成带 ProblemDetails
正文的 HTTP 404 状态代码。 例如:
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
禁用 ProblemDetails 响应
当 SuppressMapClientErrors 属性设置为 true
时,会禁止自动创建错误状态代码的 ProblemDetails
。 添加以下代码:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
使用 [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
头发送的请求。
查看或下载示例代码。 (下载方法)。
ASP.NET Core Web API 中控制器操作的返回类型
处理 ASP.NET Core Web API 中的错误
ASP.NET Core Web API 中的自定义格式化程序
设置 ASP.NET Core Web API 中响应数据的格式
带有 Swagger/OpenAPI 的 ASP.NET Core Web API 文档
在 ASP.NET Core 中路由到控制器操作
使用端口隧道 Visual Studio 调试 Web API
使用 ASP.NET Core 创建 Web API
ASP.NET Core 支持使用控制器或使用最少的 API 创建 Web API。 Web API 中的控制器是派生自 ControllerBase 的类。 本文介绍了如何使用控制器处理 Web API 请求。 有关在没有控制器的情况下创建 Web API 的信息,请参阅教程:使用 ASP.NET Core 创建最小 API。
ControllerBase 类
基于控制器的 Web API 包含一个或多个派生自 ControllerBase 的控制器类。 Web API 项目模板提供了一个入门版控制器:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
Web API 控制器通常应派生自 ControllerBase 而不是 Controller。 Controller
派生自 ControllerBase,并添加对视图的支持,因此它用于处理 Web 页面,而不是 Web API 请求。 如果同一控制器必须支持视图和 Web API,则派生自 Controller
。
ControllerBase
类提供了很多用于处理 HTTP 请求的属性和方法。 例如,CreatedAtAction 返回 201 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
下表包含 ControllerBase
中的方法示例。
有关可用方法和属性的列表,请参阅 ControllerBase。
Microsoft.AspNetCore.Mvc 命名空间提供可用于配置 Web API 控制器的行为和操作方法的属性。 下述示例使用属性来指定受支持的 HTTP 操作谓词和所有可返回的已知 HTTP 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
以下是可用属性的更多示例。
有关包含可用属性的列表,请参阅 Microsoft.AspNetCore.Mvc 命名空间。
ApiController 属性
[ApiController]
属性可应用于控制器类,以启用下述 API 特定的固定行为:
属性路由要求
自动 HTTP 400 响应
绑定源参数推理
Multipart/form-data 请求推理
错误状态代码的问题详细信息
特定控制器上的属性
[ApiController]
属性可应用于特定控制器,如项目模板中的以下示例所示:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
多个控制器上的属性
在多个控制器上使用该属性的一种方法是创建通过 [ApiController]
属性批注的自定义基控制器类。 下述示例展示了自定义基类以及从其派生的控制器:
[ApiController]
public class MyControllerBase : ControllerBase
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
程序集上的属性
[ApiController]
属性可应用于程序集。 如果将 [ApiController]
属性应用于程序集,程序集中的所有控制器都将应用 [ApiController]
属性。 无法针对单个控制器执行选择退出操作。 将程序集级属性应用于 Program.cs
文件:
using Microsoft.AspNetCore.Mvc;
[assembly: ApiController]
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
特性路由要求
[ApiController]
属性使属性路由成为要求。 例如:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
不能通过由 UseEndpoints
、UseMvc 或 UseMvcWithDefaultRoute 定义的传统路由访问操作。
自动 HTTP 400 响应
[ApiController]
属性使模型验证错误自动触发 HTTP 400 响应。 因此,操作方法中不需要以下代码:
if (!ModelState.IsValid)
return BadRequest(ModelState);
ASP.NET Core MVC 使用 ModelStateInvalidFilter 操作筛选器来执行上述检查。
默认 BadRequest 响应
下述响应正文是序列化类型的示例:
"": [
"A non-empty request body is required."
HTTP 400 响应的默认响应类型为 ValidationProblemDetails。 下述响应正文是序列化类型的示例:
"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 规范。
要使自动和自定义响应保持一致,请调用 ValidationProblem 方法,而不是 BadRequest。 ValidationProblem
返回 ValidationProblemDetails 对象以及自动响应。
记录自动 400 响应
若要记录自动 400 响应,请将 InvalidModelStateResponseFactory 委托属性设置为执行自定义处理。 默认情况下,InvalidModelStateResponseFactory
使用 ProblemDetailsFactory 创建 ValidationProblemDetails 实例。
以下示例演示如何检索 ILogger<TCategoryName> 实例以记录有关自动 400 响应的信息:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
var logger = context.HttpContext.RequestServices
.GetRequiredService<ILogger<Program>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails
// response.
// To produce a custom response, return a different implementation of
// IActionResult instead.
return builtInFactory(context);
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
禁用自动 400 响应
若要禁用自动 400 行为,请将 SuppressModelStateInvalidFilter 属性设置为 true
。 添加以下突出显示的代码:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
绑定源参数推理
绑定源特性定义可找到操作参数值的位置。 存在以下绑定源特性:
当值可能包含 %2f
(即 /
)时,请勿使用 [FromRoute]
。 %2f
不会转换为 /
(非转义形式)。 如果值可能包含 %2f
,则使用 [FromQuery]
。
如果没有 [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();
products = _productsInMemoryStore;
return products;
[ApiController]
属性将推理规则应用于操作参数的默认数据源。 借助这些规则,无需通过将属性应用于操作参数来手动识别绑定源。 绑定源推理规则的行为如下:
[FromBody]
针对未在 DI 容器中注册的复杂类型参数进行推断。 [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 order)
禁用推理规则
若要禁用绑定源推理,请将 SuppressInferBindingSourcesForParameters 设置为 true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
[ApiController]
属性对 IFormFile 和 IFormFileCollection 类型的操作参数应用推理规则。 为这些类型推断 multipart/form-data
请求内容类型。
要禁用默认行为,请将 SuppressConsumesConstraintForFormFileParameters 属性设置为 true
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
错误状态代码的问题详细信息
MVC 将错误结果(状态代码为 400 或更高)转换为状态代码为 ProblemDetails 的结果。 ProblemDetails
类型基于 RFC 7807 规范,用于提供 HTTP 响应中计算机可读的错误详细信息。
考虑在控制器操作中使用以下代码:
if (pet == null)
return NotFound();
NotFound
方法会生成带 ProblemDetails
正文的 HTTP 404 状态代码。 例如:
type: "https://tools.ietf.org/html/rfc7231#section-6.5.4",
title: "Not Found",
status: 404,
traceId: "0HLHLV31KRN83:00000001"
禁用 ProblemDetails 响应
当 SuppressMapClientErrors 属性设置为 true
时,会禁止自动创建错误状态代码的 ProblemDetails
:
using Microsoft.AspNetCore.Mvc;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
使用 [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
头发送的请求。
查看或下载示例代码。 (下载方法)。
ASP.NET Core Web API 中控制器操作的返回类型
处理 ASP.NET Core Web API 中的错误
ASP.NET Core Web API 中的自定义格式化程序
设置 ASP.NET Core Web API 中响应数据的格式
带有 Swagger/OpenAPI 的 ASP.NET Core Web API 文档
在 ASP.NET Core 中路由到控制器操作
使用端口隧道 Visual Studio 调试 Web API
使用 ASP.NET Core 创建 Web API
ASP.NET Core 支持使用 C# 创建 RESTful 服务,也称为 Web API。 若要处理请求,Web API 使用控制器。 Web API 中的控制器是派生自 ControllerBase
的类。 本文介绍了如何使用控制器处理 Web API 请求。
查看或下载示例代码。 (下载方法)。
ControllerBase 类
Web API 包含一个或多个派生自 ControllerBase 的控制器类。 Web API 项目模板提供了一个入门版控制器:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
不要通过从 Controller 类派生来创建 Web API 控制器。 Controller
派生自 ControllerBase
,并添加对视图的支持,因此它用于处理 Web 页面,而不是 Web API 请求。 此规则有一个例外:如果打算为视图和 Web API 使用相同的控制器,则从 Controller
派生控制器。
ControllerBase
类提供了很多用于处理 HTTP 请求的属性和方法。 例如,ControllerBase.CreatedAtAction
返回 201 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
下面是 ControllerBase
提供的方法的更多示例。
有关可用方法和属性的列表,请参阅 ControllerBase。
Microsoft.AspNetCore.Mvc 命名空间提供可用于配置 Web API 控制器的行为和操作方法的属性。 下述示例使用属性来指定受支持的 HTTP 操作谓词和所有可返回的已知 HTTP 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
以下是可用属性的更多示例。
有关包含可用属性的列表,请参阅 Microsoft.AspNetCore.Mvc 命名空间。
ApiController 属性
[ApiController]
属性可应用于控制器类,以启用下述 API 特定的固定行为:
属性路由要求
自动 HTTP 400 响应
绑定源参数推理
Multipart/form-data 请求推理
错误状态代码的问题详细信息
特定控制器上的属性
[ApiController]
属性可应用于特定控制器,如项目模板中的以下示例所示:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
多个控制器上的属性
在多个控制器上使用该属性的一种方法是创建通过 [ApiController]
属性批注的自定义基控制器类。 下述示例展示了自定义基类以及从其派生的控制器:
[ApiController]
public class MyControllerBase : ControllerBase
[Produces(MediaTypeNames.Application.Json)]
[Route("[controller]")]
public class PetsController : MyControllerBase
程序集上的属性
[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 响应
下述请求正文是序列化类型的示例:
"": [
"A non-empty request body is required."
HTTP 400 响应的默认响应类型为 ValidationProblemDetails。 下述请求正文是序列化类型的示例:
"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 规范。
要使自动和自定义响应保持一致,请调用 ValidationProblem 方法,而不是 BadRequest。 ValidationProblem
返回 ValidationProblemDetails 对象以及自动响应。
记录自动 400 响应
若要记录自动 400 响应,请将 InvalidModelStateResponseFactory 委托属性设置为在 Startup.ConfigureServices
中执行自定义处理。 默认情况下,InvalidModelStateResponseFactory
使用 ProblemDetailsFactory 创建 ValidationProblemDetails 实例。
以下示例演示如何检索 ILogger<TCategoryName> 实例以记录有关自动 400 响应的信息:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
// To preserve the default behavior, capture the original delegate to call later.
var builtInFactory = options.InvalidModelStateResponseFactory;
options.InvalidModelStateResponseFactory = context =>
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<Startup>>();
// Perform logging here.
// ...
// Invoke the default behavior, which produces a ValidationProblemDetails response.
// To produce a custom response, return a different implementation of IActionResult instead.
return builtInFactory(context);
禁用自动 400 响应
若要禁用自动 400 行为,请将 SuppressModelStateInvalidFilter 属性设置为 true
。 将以下突出显示的代码添加到 Startup.ConfigureServices
:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
绑定源参数推理
绑定源特性定义可找到操作参数值的位置。 存在以下绑定源特性:
当值可能包含 %2f
(即 /
)时,请勿使用 [FromRoute]
。 %2f
不会转换为 /
(非转义形式)。 如果值可能包含 %2f
,则使用 [FromQuery]
。
如果没有 [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();
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 order)
禁用推理规则
若要禁用绑定源推理,请将 SuppressInferBindingSourcesForParameters 设置为 true
。 在 Startup.ConfigureServices
中添加下列代码:
services.AddControllers()
.ConfigureApiBehaviorOptions(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
options.SuppressMapClientErrors = true;
options.ClientErrorMapping[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
[ApiController]
属性对 IFormFile 和 IFormFileCollection 类型的操作参数应用推理规则。 为这些类型推断 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[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
错误状态代码的问题详细信息
MVC 将错误结果(状态代码为 400 或更高)转换为状态代码为 ProblemDetails 的结果。 ProblemDetails
类型基于 RFC 7807 规范,用于提供 HTTP 响应中计算机可读的错误详细信息。
考虑在控制器操作中使用以下代码:
if (pet == null)
return NotFound();
NotFound
方法会生成带 ProblemDetails
正文的 HTTP 404 状态代码。 例如:
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[StatusCodes.Status404NotFound].Link =
"https://httpstatuses.com/404";
options.DisableImplicitFromServicesParameters = true;
使用 [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
头发送的请求。
ASP.NET Core Web API 中控制器操作的返回类型
处理 ASP.NET Core Web API 中的错误
ASP.NET Core Web API 中的自定义格式化程序
设置 ASP.NET Core Web API 中响应数据的格式
带有 Swagger/OpenAPI 的 ASP.NET Core Web API 文档
在 ASP.NET Core 中路由到控制器操作
使用 ASP.NET Core 创建 Web API
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
不要通过从 Controller 类派生来创建 Web API 控制器。 Controller
派生自 ControllerBase
,并添加对视图的支持,因此它用于处理 Web 页面,而不是 Web API 请求。 此规则有一个例外:如果打算为视图和 Web API 使用相同的控制器,则从 Controller
派生控制器。
ControllerBase
类提供了很多用于处理 HTTP 请求的属性和方法。 例如,ControllerBase.CreatedAtAction
返回 201 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
下面是 ControllerBase
提供的方法的更多示例:
有关可用方法和属性的列表,请参阅 ControllerBase。
Microsoft.AspNetCore.Mvc 命名空间提供可用于配置 Web API 控制器的行为和操作方法的属性。 下述示例使用属性来指定受支持的 HTTP 操作谓词和所有可返回的已知 HTTP 状态代码:
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult<Pet> 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);
以下是可用属性的更多示例:
有关包含可用属性的列表,请参阅 Microsoft.AspNetCore.Mvc 命名空间。
ApiController 属性
[ApiController]
属性可应用于控制器类,以启用下述 API 特定的固定行为:
属性路由要求
自动 HTTP 400 响应
绑定源参数推理
Multipart/form-data 请求推理
错误状态代码的问题详细信息必须有兼容性版本 2.2 或更高版本,才能使用“错误状态代码的问题详细信息”功能。 必须有兼容性版本 2.1 或更高版本,才能使用其他功能。
属性路由要求
自动 HTTP 400 响应
绑定源参数推理
Multipart/form-data 请求推理这些功能需要兼容性版本为 2.1 或更高版本。
特定控制器上的属性
[ApiController]
属性可应用于特定控制器,如项目模板中的以下示例所示:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
多个控制器上的属性
在多个控制器上使用该属性的一种方法是创建通过 [ApiController]
属性批注的自定义基控制器类。 下述示例展示了自定义基类以及从其派生的控制器:
[ApiController]
public class MyControllerBase : ControllerBase
[Produces(MediaTypeNames.Application.Json)]
[Route("api/[controller]")]
public class PetsController : MyControllerBase
程序集上的属性
如果将兼容性版本设置为 2.2 或更高版本,则 [ApiController]
属性可应用于程序集。 以这种方式进行注释,会将 web API 行为应用到程序集中的所有控制器。 无法针对单个控制器执行选择退出操作。 将程序集级别的属性应用于 Startup
类两侧的命名空间声明:
[assembly: ApiController]
namespace WebApiSample
public class Startup
特性路由要求
[ApiController]
属性使属性路由成为要求。 例如:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
不能通过 UseMvc 定义的传统路由或通过 Startup.Configure
中的 UseMvcWithDefaultRoute 访问操作。
自动 HTTP 400 响应
[ApiController]
属性使模型验证错误自动触发 HTTP 400 响应。 因此,操作方法中不需要以下代码:
if (!ModelState.IsValid)
return BadRequest(ModelState);
ASP.NET Core MVC 使用 ModelStateInvalidFilter 操作筛选器来执行上述检查。
默认 BadRequest 响应
使用 2.1 的兼容性版本时,HTTP 400 响应的默认响应类型为 SerializableError。 下述请求正文是序列化类型的示例:
"": [
"A non-empty request body is required."
使用 2.2 或更高版本的兼容性版本时,HTTP 400 响应的默认响应类型为 ValidationProblemDetails。 下述请求正文是序列化类型的示例:
"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 规范。
要使自动和自定义响应保持一致,请调用 ValidationProblem 方法,而不是 BadRequest。 ValidationProblem
返回 ValidationProblemDetails 对象以及自动响应。
记录自动 400 响应
请参阅如何对模型验证错误记录自动 400 响应 (dotnet/AspNetCore.Docs#12157)。
禁用自动 400 响应
若要禁用自动 400 行为,请将 SuppressModelStateInvalidFilter 属性设置为 true
。 将以下突出显示的代码添加到 Startup.ConfigureServices
:
services.Configure<ApiBehaviorOptions>(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
绑定源参数推理
绑定源特性定义可找到操作参数值的位置。 存在以下绑定源特性:
当值可能包含 %2f
(即 /
)时,请勿使用 [FromRoute]
。 %2f
不会转换为 /
(非转义形式)。 如果值可能包含 %2f
,则使用 [FromQuery]
。
如果没有 [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();
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 order)
在 ASP.NET Core 2.1 中,集合类型参数(如列表和数组)被不正确地推断为 [FromQuery]
。 若要从请求正文中绑定参数,应对这些参数使用 [FromBody]
属性。 此行为在 ASP.NET Core 2.2 或更高版本中得到了更正,其中集合类型参数默认被推断为从正文中绑定。
禁用推理规则
若要禁用绑定源推理,请将 SuppressInferBindingSourcesForParameters 设置为 true
。 在 Startup.ConfigureServices
中添加下列代码:
services.Configure<ApiBehaviorOptions>(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
[ApiController]
属性对 IFormFile 和 IFormFileCollection 类型的操作参数应用推理规则。 为这些类型推断 multipart/form-data
请求内容类型。
要禁用默认行为,请在 Startup.ConfigureServices
中将 SuppressConsumesConstraintForFormFileParameters 属性设置为 true
:
services.Configure<ApiBehaviorOptions>(options =>
options.SuppressConsumesConstraintForFormFileParameters = true;
options.SuppressInferBindingSourcesForParameters = true;
options.SuppressModelStateInvalidFilter = true;
错误状态代码的问题详细信息
当兼容性版本为 2.2 或更高版本时,MVC 会将错误结果(状态代码为 400 或更高的结果)转换为状态代码为 ProblemDetails 的结果。 ProblemDetails
类型基于 RFC 7807 规范,用于提供 HTTP 响应中计算机可读的错误详细信息。
考虑在控制器操作中使用以下代码:
if (pet == null)
return NotFound();
NotFound
方法会生成带 ProblemDetails
正文的 HTTP 404 状态代码。 例如:
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
中添加下列代码:
使用 [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
头发送的请求。
ASP.NET Core Web API 中控制器操作的返回类型
处理 ASP.NET Core Web API 中的错误
ASP.NET Core Web API 中的自定义格式化程序
设置 ASP.NET Core Web API 中响应数据的格式
带有 Swagger/OpenAPI 的 ASP.NET Core Web API 文档
在 ASP.NET Core 中路由到控制器操作
使用 ASP.NET Core 创建 Web API