Swashbuckle查询参数IOperationFilter无法处理嵌套类问题
解决方案
出现该问题的根本原因是Swashbuckle默认对嵌套查询参数使用方括号拼接语法,而ASP.NET Core的模型绑定系统默认识别点号分隔的嵌套参数格式,二者不匹配导致参数绑定失效。你可以通过修改自定义IOperationFilter实现,递归展开嵌套属性生成符合要求的参数名:
步骤1:实现支持嵌套类型的IOperationFilter
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using System.Reflection; public class NestedQueryParameterFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 筛选所有[FromQuery]标记的复杂类型参数 var queryParameters = context.ApiDescription.ParameterDescriptions .Where(p => p.Source.Id == "Query" && p.ModelMetadata.IsComplexType) .ToList(); foreach (var param in queryParameters) { // 移除Swagger默认生成的带方括号的错误参数 var existingParam = operation.Parameters.FirstOrDefault(p => p.Name == param.Name); if (existingParam != null) { operation.Parameters.Remove(existingParam); } // 递归展开嵌套属性生成点号分隔的参数 ExpandNestedProperties(param.ModelMetadata.ModelType, param.Name, operation, context); } } private void ExpandNestedProperties(Type type, string parentName, OpenApiOperation operation, OperationFilterContext context) { // 基础类型、枚举、字符串等非复杂类型直接生成参数 if (type.IsPrimitive || type.IsEnum || type == typeof(string) || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(Guid)) { operation.Parameters.Add(new OpenApiParameter { Name = parentName, In = ParameterLocation.Query, Required = false, Schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository) }); return; } // 遍历所有公共属性,拼接点号格式的参数名 foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { var propertyName = parentName == null ? property.Name : $"{parentName}.{property.Name}"; // 支持JsonPropertyName特性自定义参数名的场景可自行在此处扩展逻辑 ExpandNestedProperties(property.PropertyType, propertyName, operation, context); } } }
步骤2:注册Filter到Swagger配置
在项目启动配置的AddSwaggerGen方法中添加Filter注册即可:
builder.Services.AddSwaggerGen(c => { c.OperationFilter<NestedQueryParameterFilter>(); // 其余原有Swagger配置保持不变 });
生效效果
配置完成后Swagger生成的请求参数将自动使用点号分隔嵌套层级,最终请求URL格式如下:https://Url/Path?contains=string&pagination.pageSize=0&pagination.pageNumber=0
完全适配ASP.NET Core默认的模型绑定规则,嵌套参数可正常绑定取值。
内容的提问来源于stack exchange,提问作者Mateech
相关产品推荐
相关产品推荐

