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

NSwag生成代码出现随机类名,GUI不保留JSON命名问题求助

解决NSwag生成C#客户端类名自动序列化(Body1/Response1)及保留原JSON属性名问题

问题根源

类名生成Body1/Response1这类序列名,是因为OpenAPI文档中的请求/响应体schema没有明确指定title或未通过引用关联到命名schema;而GUI强制转UpperCamelCase,是因为默认启用了属性名驼峰转换规则。

解决方案

1. 自定义类名生成逻辑,替换自动序列名

通过实现ITypeNameGenerator,让NSwag优先使用schema的标题,或对自动生成的类型名做自定义处理,避免无意义的数字后缀。

2. 确保原JSON属性名保留

完善自定义属性名生成器的配置,并开启JsonPropertyName属性生成,保证序列化时使用原名称。

修改后的完整代码

var document = NSwag.OpenApiDocument.FromUrlAsync(url).Result;
var settings = new NSwag.CodeGeneration.CSharp.CSharpClientGeneratorSettings
{
    GenerateClientClasses = true,
    GenerateClientInterfaces = true,
    InjectHttpClient = true,
    DisposeHttpClient = true,
    GenerateExceptionClasses = true,
    ExceptionClass = "EdiException",
    WrapDtoExceptions = true,
    UseHttpClientCreationMethod = false,
    HttpClientType = "System.Net.Http.HttpClient",
    UseHttpRequestMessageCreationMethod = false,
    UseBaseUrl = true,
    GenerateBaseUrlProperty = true,
    GenerateSyncMethods = false,
    GeneratePrepareRequestAndProcessResponseAsAsyncMethods = false,
    ExposeJsonSerializerSettings = true,
    ClientClassAccessModifier = "public",
    ClassName = "CancellationService",

    CSharpGeneratorSettings =
    {
        TypeAccessModifier = "public",
        Namespace = "Edlund.NonLifeCore.Shared.DK.CancellationService",
        // 赋值自定义属性名生成器,保留原命名
        PropertyNameGenerator = new CustomRespectSwaggerPropertyNameGenerator(),
        GenerateDataAnnotations = true,
        GenerateJsonMethods = true,
        GenerateDefaultValues = true,
        ClassStyle = NJsonSchema.CodeGeneration.CSharp.CSharpClassStyle.Poco,
        JsonLibrary = NJsonSchema.CodeGeneration.CSharp.CSharpJsonLibrary.NewtonsoftJson,
        // 开启JsonPropertyName属性生成,确保序列化使用原属性名
        GenerateJsonPropertyNameAttribute = true,
        // 自定义类名生成器,替换Body1/Response1这类序列名
        TypeNameGenerator = new CustomTypeNameGenerator()
    }
};

var resolver = new NJsonSchema.CodeGeneration.CSharp.CSharpTypeResolver(settings.CSharpGeneratorSettings);
var generator = new NSwag.CodeGeneration.CSharp.CSharpClientGenerator(document, settings, resolver);
var client = generator.GenerateFile();

File.WriteAllLines(OutputPath + ".cs", new List<string> { client });
}
}

public class CustomRespectSwaggerPropertyNameGenerator : IPropertyNameGenerator
{
    string IPropertyNameGenerator.Generate(JsonSchemaProperty property)
    {
        // 保留原属性名,仅替换非法字符
        return property.Name.Replace('_', '-')
            .Replace("@", "")
            .Replace(".", "-");
    }
}

public class CustomTypeNameGenerator : ITypeNameGenerator
{
    public string Generate(JsonSchema schema, string typeNameHint, IEnumerable<string> reservedTypeNames)
    {
        // 优先使用OpenAPI schema中定义的Title作为类名
        if (!string.IsNullOrWhiteSpace(schema.Title))
        {
            var cleanedTitle = schema.Title.Trim();
            // 确保类名符合C#命名规范(首字母大写)
            return char.ToUpper(cleanedTitle[0]) + cleanedTitle.Substring(1);
        }

        // 处理自动生成的typeNameHint(如Body1、Response1)
        if (!string.IsNullOrWhiteSpace(typeNameHint))
        {
            // 移除数字后缀,并转换为符合C#规范的名称
            var baseName = typeNameHint.TrimEnd('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
            // 可根据需求调整命名规则,比如把Body改为Request
            baseName = baseName.Replace("Body", "Request");
            return char.ToUpper(baseName[0]) + baseName.Substring(1);
        }

        // 兜底命名
        return "UnnamedDto";
    }
}

关键配置说明

  • CustomTypeNameGenerator:优先读取OpenAPI schema的title字段作为类名;如果没有title,则清理自动生成的typeNameHint(移除数字后缀、替换关键词),生成有意义的类名。
  • CustomRespectSwaggerPropertyNameGenerator:直接使用原JSON属性名,仅替换C#属性名不允许的字符,确保命名保留原始格式。
  • GenerateJsonPropertyNameAttribute = true:生成[JsonPropertyName("原属性名")]属性,保证Newtonsoft.Json序列化时使用原始名称,而非默认的驼峰转换。

额外建议

如果有权限修改OpenAPI文档,建议给所有内联的请求/响应schema添加title字段,这样NSwag可以直接使用该标题生成类名,无需自定义TypeNameGenerator,效果更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 09:19:51