如何在Swashbuckle中为指定PUT端点添加必填If-Match请求头?
给Swashbuckle的PUT端点添加必填If-Match请求头
嘿Thomas,我刚好处理过类似的需求,这里有几个实用的方法帮你把这个规则加到Swashbuckle文档里:
方法一:使用操作过滤器(OperationFilter)
这是最直接的方式,通过自定义过滤器批量修改所有PUT端点的Swagger文档元数据:
- 创建一个实现
IOperationFilter的过滤器类:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; public class RequireIfMatchHeaderFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 仅对PUT请求的端点生效 if (context.ApiDescription.HttpMethod.Equals("PUT", StringComparison.OrdinalIgnoreCase)) { operation.Parameters ??= new List<OpenApiParameter>(); // 添加必填的If-Match请求头,并补充说明 operation.Parameters.Add(new OpenApiParameter { Name = "If-Match", In = ParameterLocation.Header, Required = true, Description = "必须携带资源此前的ETag值,用于实现并发控制" }); } } }
- 在Swagger配置中注册这个过滤器:
builder.Services.AddSwaggerGen(c => { // 你的其他Swagger配置... c.OperationFilter<RequireIfMatchHeaderFilter>(); });
配置完成后,所有PUT端点的Swagger文档里都会自动出现必填的If-Match请求头,消费者一眼就能看到规则。
方法二:结合自定义属性标记特定端点
如果只想给部分PUT端点添加这个规则,可以用自定义属性来精准控制:
- 先定义一个标记用的属性:
[AttributeUsage(AttributeTargets.Method)] public class RequireIfMatchHeaderAttribute : Attribute { }
- 修改过滤器,只对标记了该属性的PUT方法生效:
public void Apply(OpenApiOperation operation, OperationFilterContext context) { var hasAttribute = context.MethodInfo .GetCustomAttributes(typeof(RequireIfMatchHeaderAttribute), false) .Any(); if (hasAttribute && context.ApiDescription.HttpMethod.Equals("PUT", StringComparison.OrdinalIgnoreCase)) { // 复用添加If-Match请求头的逻辑 operation.Parameters ??= new List<OpenApiParameter>(); operation.Parameters.Add(new OpenApiParameter { Name = "If-Match", In = ParameterLocation.Header, Required = true, Description = "必须携带资源此前的ETag值,用于实现并发控制" }); } }
- 在需要的PUT方法上标记属性:
[HttpPut("{id}")] [RequireIfMatchHeader] public IActionResult UpdateResource(int id, [FromBody] ResourceDto dto) { // 你的业务逻辑... }
额外提示:配合后端验证
别忘了在后端实际校验If-Match头的合法性,比如在动作方法里直接获取并验证:
[HttpPut("{id}")] public IActionResult UpdateResource( int id, [FromBody] ResourceDto dto, [FromHeader(Name = "If-Match")] string ifMatch) { if (string.IsNullOrEmpty(ifMatch)) { return BadRequest("必须提供If-Match请求头"); } // 对比资源当前的ETag与传入的ifMatch值,处理并发逻辑... }
这样文档规则和后端实际校验就完全对应上了,消费者也能清楚知道该怎么调用接口~
内容的提问来源于stack exchange,提问作者Thomas Hendrickx
相关产品推荐
相关产品推荐

