跳到主要内容 基于.NET的Web API控制器及方法注解属性 | 极客日志
C#
基于.NET的Web API控制器及方法注解属性 .NET Web API开发中常用的注解属性。内容包括路由与HTTP方法定义(如[ApiController]、[Route])、参数绑定源选择(如[FromBody]、[FromQuery])、响应类型与格式控制(如[Produces]、[ProducesResponseType])、授权与认证机制(如[Authorize])以及Swagger文档增强(如[SwaggerOperation])。通过具体代码示例,阐述了各属性的作用、参数及使用场景,旨在帮助开发者构建规范的API接口。
魔法巫师 发布于 2026/4/6 更新于 2026/4/18 5 浏览1. 路由与 HTTP 方法 (Microsoft.AspNetCore.Mvc 命名空间)
[ApiController]
作用: 应用于控制器类。启用 API 特定的约定和行为:
自动 HTTP 400 响应: 当模型验证失败时,自动返回 BadRequestResult (400),包含 ModelState 错误详情。
推断参数源: 自动推断复杂类型参数来自请求体 ([FromBody]),简单类型来自查询字符串 ([FromQuery]) 或路由 ([FromRoute])。
属性路由要求: 要求控制器使用 [Route] 或 [HttpGet] 等属性定义路由。
错误状态码详细信息: 在 4xx 错误响应中包含 ProblemDetails 格式的错误信息。
[Route]
作用: 定义控制器或 Action 方法的 URL 路由模板。可应用于控制器(为所有 Action 方法设置前缀)或 Action 方法。
参数:
Template (必填): URL 路由模板字符串。可以使用 [controller](控制器名去掉 'Controller' 后缀)、[action](方法名)占位符。模板中可用 {param} 定义路由参数。
Name (可选): 为路由指定一个唯一名称,用于生成 URL (IUrlHelper 或链接)。
Order (可选): 路由匹配的顺序(数字越小优先级越高)。
HTTP 方法属性 ([HttpGet], [HttpPost], [HttpPut], [HttpDelete], [HttpPatch], [HttpHead], [HttpOptions])
作用: 指定 Action 方法响应哪个 HTTP 方法(动词)。它们本质上是带有固定 HttpMethod 的 [HttpMethod] 属性的快捷方式。通常与 [Route] 或内联路由模板一起使用。
参数:
Template (可选): 内联的路由模板字符串。如果提供,它会覆盖或附加到控制器路由模板。
Name (可选): 路由名称。
Order (可选): 路由顺序。
[AcceptVerbs]
作用: 允许 Action 方法响应多个 HTTP 方法。指定一个或多个 HTTP 方法字符串(如 "GET", "POST", "PATCH")。
参数:
verbs (必填): 允许的 HTTP 方法列表。
微信扫一扫,关注极客日志 微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online
[NonAction]
作用: 标记控制器类中的某个公共方法不是 一个 Action 方法。防止 MVC 框架将其视为可路由的 HTTP 端点。
public class UsersController : ControllerBase
{
[HttpGet("{id}" ) ]
public IActionResult GetUser (int id )
{
...
}
[NonAction ]
public string GeneratePasswordResetToken ()
{
...
}
}
[AcceptVerbs("GET" , "HEAD" ) ]
public IActionResult GetInfo (int id )
{
...
}
[HttpGet ]
public IEnumerable<Product> GetAll ()
{
...
}
[HttpGet("{id}" ) ]
public ActionResult<Product> GetById (int id )
{
...
}
[HttpPost("create" ) ]
public IActionResult CreateProduct ([FromBody] Product product )
{
...
}
[HttpPut("{id}" ) ]
public IActionResult UpdateProduct (int id, [FromBody] Product product )
{
...
}
[HttpDelete("{id}" ) ]
public IActionResult DeleteProduct (int id )
{
...
}
[ApiController ]
[Route("api/v{version:apiVersion}/[controller]" ) ]
public class OrdersController : ControllerBase
{
[HttpGet("{id:int}" ) ]
public IActionResult GetById (int id )
{
...
}
[HttpPost ]
public IActionResult Create (Order order )
{
...
}
[Route("~/legacy/orders" ) ]
public IActionResult GetLegacyOrders ()
{
...
}
}
[ApiController ]
[Route("api/[controller]" ) ]
public class ProductsController : ControllerBase
{
}
2. 参数绑定源 (Microsoft.AspNetCore.Mvc 命名空间)
[FromBody]
作用: 指示参数应从 HTTP 请求的正文中绑定。通常用于绑定复杂的 JSON/XML 对象。在 [ApiController] 中,复杂类型参数默认使用此来源。
[FromQuery]
作用: 指示参数应从 URL 查询字符串中绑定。在 [ApiController] 中,简单类型参数默认使用此来源。
[FromRoute]
作用: 指示参数应从 URL 路由数据中绑定(由路由模板中的 {param} 定义)。在 [ApiController] 中,如果路由模板中有匹配名称的参数,默认使用此来源。
[FromHeader]
[FromForm]
作用: 指示参数应从 HTTP 请求的已提交表单数据中绑定。常用于 multipart/form-data 或 application/x-www-form-urlencoded 内容类型。
[FromServices]
作用: 指示参数应通过依赖注入 (DI) 容器解析获得,而不是从请求中绑定。用于在 Action 方法中注入服务。
[BindRequired] / [BindNever]
作用:
[BindRequired]: 指示参数是必需的,如果无法绑定(如从查询字符串缺少值),则模型验证会失败。
[BindNever]: 指示参数应被完全忽略,不进行绑定。常用于防止过度提交攻击(Mass Assignment)。
public class UserUpdateModel
{
public string Username { get ; set ; }
[BindRequired ]
public string Email { get ; set ; }
[BindNever ]
public bool IsAdmin { get ; set ; }
}
[HttpPost ]
public IActionResult PlaceOrder (Order order, [FromServices] IOrderService orderService )
{
orderService.ProcessOrder(order);
return Ok();
}
[HttpPost("upload" ) ]
public IActionResult UploadFile ([FromForm] IFormFile file , [FromForm] string description )
{
}
[HttpGet ]
public IActionResult Get ([FromHeader(Name = "X-Client-Version" )] string clientVersion)
{
}
[HttpGet("{id:int}" ) ]
public IActionResult GetById ([FromRoute] int id )
{
}
[HttpGet("search" ) ]
public IActionResult SearchProducts ([FromQuery] string name, [FromQuery] int ? minPrice )
{
}
[HttpPost ]
public IActionResult Create ([FromBody] Product product )
{
}
3. 响应类型与格式 (Microsoft.AspNetCore.Mvc 命名空间)
[Produces]
作用: 应用于控制器或 Action 方法,指定 Action 方法返回的响应内容类型(MIME 类型,如 "application/json", "application/xml")。影响 Content-Type 响应头和客户端内容协商。
参数:
contentType (必填): 内容类型字符串。
Type (可选): 返回对象类型的 Type (常用于 Swagger 文档)。
StatusCodes (可选): 关联的状态码数组 (常用于 Swagger 文档)。
[Consumes]
作用: 应用于控制器或 Action 方法,指定 Action 方法接受的请求内容类型(MIME 类型)。用于内容协商,如果请求的 Content-Type 不匹配,框架会返回 415 Unsupported Media Type。
参数:
contentType (必填): 内容类型字符串。
[ProducesResponseType]
作用:强烈推荐使用! 指定 Action 方法返回的特定 HTTP 状态码及其关联的响应类型。主要用于:
Swagger/OpenAPI 文档生成: 为工具(如 SwaggerUI)提供清晰的 API 契约。
增强代码可读性: 明确说明方法可能返回哪些状态码。
参数:
statusCode (必填): HTTP 状态码(如 200, 201, 400, 404, 500)。建议使用 StatusCodes 常量(如 StatusCodes.Status200OK)。
Type (可选): 成功响应(2xx)时返回的对象类型。对于错误响应(4xx/5xx),通常是 ProblemDetails 或 string。
ContentType (可选): 响应的内容类型。
[ProducesDefaultResponseType]
作用: 当无法匹配其他 [ProducesResponseType] 指定的状态码时,指定一个默认的响应类型。常用于捕获未明确声明的错误(如 500 Internal Server Error)。
参数:
Type (可选): 默认响应的对象类型(通常是 ProblemDetails)。
[HttpDelete("{id}" ) ]
[ProducesResponseType(StatusCodes.Status204NoContent) ]
[ProducesResponseType(StatusCodes.Status404NotFound) ]
[ProducesDefaultResponseType(typeof(ProblemDetails)) ]
public IActionResult Delete (int id )
{
try
{
return NoContent();
}
catch (NotFoundException)
{
return NotFound();
}
}
[HttpGet("{id}" ) ]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(Product)) ]
[ProducesResponseType(StatusCodes.Status404NotFound) ]
[ProducesResponseType(StatusCodes.Status400BadRequest) ]
public ActionResult<Product> GetById (int id )
{
if (id <= 0 )
return BadRequest("ID must be positive" );
var product = _repository.GetProduct(id);
if (product == null )
return NotFound();
return product;
}
[HttpPost ]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(Product)) ]
[ProducesResponseType(StatusCodes.Status400BadRequest, Type = typeof(ValidationProblemDetails)) ]
public async Task<ActionResult<Product>> Create([FromBody] Product product)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
var createdProduct = await _repository.AddProductAsync(product);
return CreatedAtAction(nameof (GetById), new { id = createdProduct.Id }, createdProduct);
}
[HttpPost ]
[Consumes("application/json" ) ]
public IActionResult Create ([FromBody] Product product )
{
...
}
[HttpPost("upload" ) ]
[Consumes("multipart/form-data" ) ]
public IActionResult Upload ([FromForm] IFormFile file )
{
...
}
[ApiController ]
[Route("api/[controller]" ) ]
[Produces("application/json" ) ]
public class ProductsController : ControllerBase
{
[HttpGet("{id}" ) ]
[Produces("application/xml" ) ]
public Product GetById (int id )
{
...
}
[HttpGet ]
[Produces("application/json" , "application/xml" ) ]
public IEnumerable<Product> GetAll ()
{
...
}
}
4. 授权与认证 (Microsoft.AspNetCore.Authorization 命名空间)
[Authorize]
作用: 要求用户必须经过认证(登录)才能访问该控制器或 Action 方法。如果未认证,返回 401 Unauthorized。可应用于控制器(保护所有方法)或单个 Action 方法。
参数:
AuthenticationSchemes (可选): 指定使用的认证方案(如 "Bearer", "Cookies")。
Policy (可选): 指定授权策略名称(需要在 Startup.cs 中配置策略)。
Roles (可选): 指定允许访问的用户角色(逗号分隔)。用户需要拥有其中至少一个角色。
[AllowAnonymous]
作用: 允许匿名用户访问被 [Authorize] 保护的控制器或 Action 方法。通常用于登录、注册等不需要认证的接口。
示例: 见上面 [Authorize] 示例中的 PublicInfo 方法。
[Authorize(Policy = "...")]
作用: 使用自定义授权策略进行访问控制。策略在 Startup.cs 的 ConfigureServices 中使用 services.AddAuthorization 配置,可以包含复杂的授权要求(如年龄限制、声明要求、自定义处理程序)。
[RequiredScope] (通常用于 Azure AD / Microsoft Identity Platform)
作用: 要求请求的访问令牌 (access_token) 必须包含指定的作用域 (Scope)。这是实现 OAuth2 权限控制的关键。
参数:
RequiredScopes (必填): 要求的作用域数组。
[HttpGet("reports" ) ]
[RequiredScope("Reports.Read" , "Reports.ReadWrite" ) ]
public IActionResult GetReports ()
{
...
}
services.AddAuthorization(options =>
{
options.AddPolicy("Over18" , policy => policy.RequireAssertion(context => context.User.HasClaim(c => (c.Type == "Age" && int .Parse(c.Value) >= 18 ))));
options.AddPolicy("CanDelete" , policy => policy.RequireClaim("Permission" , "Delete" ));
});
[HttpDelete("{id}" ) ]
[Authorize(Policy = "Over18" ) ]
[Authorize(Policy = "CanDelete" ) ]
public IActionResult Delete (int id )
{
...
}
[ApiController ]
[Authorize ]
[Route("api/[controller]" ) ]
public class SecureController : ControllerBase
{
[HttpGet("userinfo" ) ]
public IActionResult GetUserInfo ()
{
...
}
[HttpGet("admin" ) ]
[Authorize(Roles = "Administrator" ) ]
public IActionResult AdminOnly ()
{
...
}
}
[AllowAnonymous ]
[HttpGet("public" ) ]
public IActionResult PublicInfo ()
{
...
}
5. Swagger/OpenAPI 文档增强 (Swashbuckle.AspNetCore.Annotations 或 Microsoft.AspNetCore.Mvc)
[SwaggerOperation] (Swashbuckle)
作用: 为特定的 API 操作(Action 方法)添加摘要 (Summary) 和详细描述 (Description)。
参数:
Summary: 操作的简短摘要。
Description: 操作的详细描述。
OperationId: 自定义操作的唯一标识符(覆盖默认生成)。
Tags: 自定义操作的标签(覆盖默认的控制器名)。
[SwaggerResponse] (Swashbuckle)
作用: 替代或补充 [ProducesResponseType],为 Swagger 提供更详细的响应信息(如响应头、示例)。与 [ProducesResponseType] 通常一起使用或单独使用。
参数:
statusCode (必填): HTTP 状态码。
Type (可选): 响应体类型。
Description (可选): 响应的描述。
ContentTypes (可选): 响应的内容类型。
[SwaggerParameter] (Swashbuckle)
作用: 为参数添加描述或指定其是否必需(覆盖默认推断)。
参数:
Name: 参数名称。
Description: 参数描述。
Required: 是否必需(覆盖默认)。
In: 参数位置 (ParameterLocation.Query, .Path, .Header, .Body),覆盖默认推断。
[SwaggerSchema] (Swashbuckle)
作用: 应用于模型类或属性,为 Swagger Schema 提供额外信息(如描述、示例值、是否只读/必填)。
参数:
Description: 模型或属性的描述。
ReadOnly: 是否只读(在响应中出现,不应在请求中发送)。
Required: 是否必需(覆盖数据注解的 [Required] 对于 Swagger 的影响)。
Example: 提供示例值。
[ProducesErrorResponseType] (AspNetCore.Mvc) - 与 Swagger 配合
作用: 当与 [ProducesDefaultResponseType] 或特定错误 [ProducesResponseType] 结合使用时,明确告知 Swagger 默认错误响应的类型(通常是 ProblemDetails 或 HttpValidationProblemDetails)。
[ApiController ]
[ProducesErrorResponseType(typeof(ProblemDetails)) ]
[Route("api/[controller]" ) ]
public class MyController : ControllerBase
{
}
public class Product
{
[SwaggerSchema("The unique identifier of the product" , ReadOnly = true) ]
public int Id { get ; set ; }
[Required ]
[SwaggerSchema("The name of the product" , Example = "Apple iPhone 13" ) ]
public string Name { get ; set ; }
[SwaggerSchema("The price in USD" , Format = "decimal" ) ]
public decimal Price { get ; set ; }
}
[HttpGet("search" ) ]
public IActionResult Search ([FromQuery, SwaggerParameter("Name of the product to search for" , Required = true )] string name,
[FromQuery, SwaggerParameter ("Minimum price filter" )] decimal ? minPrice)
{
...
}
[HttpGet("{id}" ) ]
[ProducesResponseType(StatusCodes.Status200OK) ]
[SwaggerResponse(200, "The product was found" , typeof(Product)) ]
[SwaggerResponse(404, "The product does not exist" , typeof(NotFoundResult)) ]
public ActionResult<Product> GetById (int id )
{
...
}
[HttpPost ]
[SwaggerOperation(
Summary = "Creates a new product" ,
Description = "Requires administrator privileges. Returns the created product with its generated ID." ,
OperationId = "CreateProduct" ,
Tags = new[ ] { "Admin" }
)]
public ActionResult<Product> Create ([FromBody] Product product )
{
...
}