如何让Swagger在示例Schema中包含object类型属性?
问题:Swagger UI中Object类型属性未显示在Schema示例中
我有一个端点标记了如下特性(还有其他返回类型的特性):
[SwaggerResponse(HttpCodeOk, Type = typeof(BatchProcessStagingInfo))]
返回类型定义如下:
public class BatchProcessStagingInfo { public Guid RecordId { get; set; } public string ItemType { get; set; } = "person"; public object PersonData { get; set; } public string Status { get; set; } public string Action { get; set; } }
项目基于.NET 6.0,将PersonData声明为object类型以确保派生类属性可正常序列化,实际运行时各种派生类型赋值都能正常工作,但Swagger UI的示例Schema里PersonData属性被省略,当前显示示例如下:
{ "recordId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemType": "string", "status": "string", "action": "string" }
需要让object类型属性出现在示例Schema中,达到如下效果:
{ "recordId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", "itemType": "string", "personData": {}, "status": "string", "action": "string" }
解决方法
1. 添加Xml注释标记属性
给PersonData属性添加Xml注释,Swagger会自动识别并保留该属性:
/// <summary> /// 存储人员相关数据 /// </summary> public object PersonData { get; set; }
注意要确保项目已启用Xml文档生成,并在Swagger配置中引入对应的Xml文件。
2. 自定义Schema过滤器强制保留Object属性
创建一个自定义的Schema过滤器,遍历类型属性,将object类型的属性添加到Swagger Schema中:
public class ObjectPropertySchemaFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { var type = context.Type; // 转驼峰命名,适配Swagger默认格式 var propNameResolver = new JsonNamingPolicy.CamelCaseNamingPolicy(); foreach (var property in type.GetProperties()) { if (property.PropertyType == typeof(object)) { var propName = propNameResolver.ConvertName(property.Name); if (!schema.Properties.ContainsKey(propName)) { schema.Properties.Add(propName, new OpenApiSchema { Type = "object", Nullable = true, Description = "人员数据对象" }); } } } } }
然后在Swagger配置中注册这个过滤器:
builder.Services.AddSwaggerGen(c => { c.SchemaFilter<ObjectPropertySchemaFilter>(); });
3. 给Object属性指定示例值
如果知道PersonData的常见结构,可以通过Xml注释的<example>标签指定示例值,Swagger会自动保留该属性并显示示例:
public class BatchProcessStagingInfo { public Guid RecordId { get; set; } public string ItemType { get; set; } = "person"; /// <example>{ "name": "张三", "age": 30, "email": "zhangsan@example.com" }</example> public object PersonData { get; set; } public string Status { get; set; } public string Action { get; set; } }
内容的提问来源于stack exchange,提问作者Steve Crane
相关产品推荐
相关产品推荐

