You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET6+NSwag生成OpenApi客户端时复杂类Schema为空问题

.NET6 + NSwag 生成OpenApi客户端时复杂类Schema为空的问题

问题场景

使用最新版NSwag和.NET6创建OpenApi客户端时,ObjectDetail这类复杂类的Schema在生成的swagger.json中为空,旧版本无此问题。相关代码如下:

ObjectDetail类

public class ObjectDetail : ObjectInfo
{
    public IDictionary<int, string> Descriptions;
    public ObjectStatus Status;
    public Dictionary<string, ParamRecItem> ParamRec;
    public Dictionary<string, StatusRecItem> StatusRec;

    public ObjectDetail()
    {
        Descriptions = new Dictionary<int, string>();
        ParamRec = new Dictionary<string, ParamRecItem>();
        StatusRec = new Dictionary<string, StatusRecItem>();
    }
}

基类ObjectInfo

public class ObjectInfo
{
    [JsonRequired] public int Id;
    [JsonRequired] public int No;

    public int? ParentId;
    public string Path;
    public string Name;
    public string Description;
    public string Info;
    public ClassInfo Class;
    public PlcInfo Plc;
}

API控制器代码

// [ApiLogging]
[HttpGet]
[Route("[controller]_getObjectDetailByName/{name}")]
[ProducesResponseType(typeof(ObjectDetail), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
public ActionResult GetObjectDetailByName(string name)
{
    ObjectDetail result = scadaService.GetObjectDetailByName(name);
    return result == null ? BadRequest() : Ok(result);
}

生成的swagger.json中对应的Schema

"ObjectDetail": {
    "type": "object",
    "additionalProperties": false
  }

Program.cs配置

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

原因分析

核心原因是Swagger/NSwag默认只识别类的属性(Property),而代码中使用的是字段(Field)。新版本的NSwag或Swashbuckle.AspNetCore(.NET6默认依赖组件)对成员识别规则更严格,仅暴露属性,不会自动包含字段,导致Schema中无对应成员信息。

解决方法

有两种可行方案:

方案1:将字段改为属性

这是.NET推荐编码规范,也是最稳妥的方式,把类中的字段替换为带get/set的属性:

修改ObjectDetail类:

public class ObjectDetail : ObjectInfo
{
    public IDictionary<int, string> Descriptions { get; set; }
    public ObjectStatus Status { get; set; }
    public Dictionary<string, ParamRecItem> ParamRec { get; set; }
    public Dictionary<string, StatusRecItem> StatusRec { get; set; }

    public ObjectDetail()
    {
        Descriptions = new Dictionary<int, string>();
        ParamRec = new Dictionary<string, ParamRecItem>();
        StatusRec = new Dictionary<string, StatusRecItem>();
    }
}

修改基类ObjectInfo:

public class ObjectInfo
{
    [JsonRequired] public int Id { get; set; }
    [JsonRequired] public int No { get; set; }

    public int? ParentId { get; set; }
    public string Path { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Info { get; set; }
    public ClassInfo Class { get; set; }
    public PlcInfo Plc { get; set; }
}

方案2:配置SwaggerGen包含字段

若不想修改现有代码结构,可在Program.cs中配置SwaggerGen,让它识别并包含类的字段:

builder.Services.AddSwaggerGen(options =>
{
    // 添加配置,让Swagger包含字段
    options.SchemaFilter<IncludeFieldsSchemaFilter>();
});

// 定义SchemaFilter类
public class IncludeFieldsSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema.Properties == null)
            schema.Properties = new Dictionary<string, OpenApiSchema>();

        // 获取所有非静态公共字段
        var fields = context.Type.GetFields(BindingFlags.Public | BindingFlags.Instance);
        foreach (var field in fields)
        {
            var propertySchema = context.SchemaGenerator.GenerateSchema(field.FieldType, context.SchemaRepository);
            // 标记带JsonRequired特性的字段为必填
            if (field.GetCustomAttributes(typeof(JsonRequiredAttribute), inherit: true).Any())
            {
                schema.Required.Add(field.Name);
            }
            schema.Properties[field.Name] = propertySchema;
        }
    }
}

注:使用此方案时,需确保ObjectStatus、ParamRecItem等依赖类也符合识别规则(要么是属性,要么被该过滤器处理)。


内容的提问来源于stack exchange,提问作者Andre Fritzsche

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 08:21:58