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
相关产品推荐
相关产品推荐

