如何在NSwag.MSBuild中重命名带@前缀的生成属性?
解决NSwag生成C#客户端时@前缀属性的命名冲突问题
针对Swagger Spec中带@前缀的属性(如@id与id)在NSwag生成C#客户端时引发的同名冲突问题,提供两种可行的解决方案:
方案一:NSwag.MSBuild配置级处理
通过修改nswag.json配置文件,添加属性重命名规则,无需编写额外编译代码,适合集成到CI/CD流程中。
方式1:使用正则替换生成器
在配置文件的CSharpClientGeneratorSettings节点下,配置RegexPropertyNameGenerator实现批量重命名:
{ "codeGenerators": { "csharp": { // 其他配置项... "propertyNameGenerator": { "typeName": "RegexPropertyNameGenerator", "parameters": { "regex": "^@(.*)", "replacement": "Key$1", "useCamelCase": false } }, // 其他配置项... } } }
- 效果:所有
@开头的属性会被重命名为Key+原属性名(首字母大写),例如@id→KeyId,@name→KeyName。 - 若需针对特定属性单独命名,可结合方式2的脚本处理器。
方式2:使用自定义脚本处理器
如果需要更灵活的命名规则,可通过ScriptSchemaProcessor编写C#脚本处理属性名:
{ "codeGenerators": { "csharp": { // 其他配置项... "schemaProcessors": [ { "typeName": "ScriptSchemaProcessor", "parameters": { "script": "foreach (var prop in context.Schema.Properties.ToList()) { if (prop.Key == \"@id\") { context.Schema.Properties.Remove(prop.Key); context.Schema.Properties[\"StringId\"] = prop.Value; } else if (prop.Key.StartsWith(\"@\")) { var cleanName = prop.Key.Substring(1); var newName = \"Key\" + char.ToUpper(cleanName[0]) + cleanName.Substring(1); context.Schema.Properties.Remove(prop.Key); context.Schema.Properties[newName] = prop.Value; } }" } } ], // 其他配置项... } } }
- 效果:
@id会被单独重命名为StringId,其他@前缀属性统一改为Key开头的命名,完全避免与原属性冲突。
方案二:代码级自定义生成逻辑
若需要高度定制的命名规则,可通过编写C#代码调用NSwag的生成API,实现自定义属性名称生成器。
示例代码
using NSwag; using NSwag.CodeGeneration.CSharp; // 加载Swagger文档 var swaggerDoc = await OpenApiDocument.FromUrlAsync("http://your-swagger-url/swagger.json"); // 配置生成器设置 var generatorSettings = new CSharpClientGeneratorSettings { Namespace = "Your.Client.Namespace", GenerateClientClasses = true, // 其他必要配置... }; // 绑定自定义属性名称生成器 generatorSettings.PropertyNameGenerator = new CustomPropertyNameGenerator(); // 生成客户端代码 var generator = new CSharpClientGenerator(swaggerDoc, generatorSettings); var clientCode = generator.GenerateFile(); // 保存生成的代码文件 File.WriteAllText("GeneratedApiClient.cs", clientCode); // 自定义属性名称生成器实现 public class CustomPropertyNameGenerator : IPropertyNameGenerator { public string Generate(OpenApiSchema schema, string propertyName, OpenApiTypeResolver typeResolver) { // 针对特定@前缀属性单独命名 if (propertyName == "@id") return "StringId"; // 批量处理其他@前缀属性 if (propertyName.StartsWith("@")) { var cleanName = propertyName.Substring(1); return $"Key{char.ToUpper(cleanName[0])}{cleanName.Substring(1)}"; } // 非@前缀属性使用默认命名规则 return new DefaultPropertyNameGenerator().Generate(schema, propertyName, typeResolver); } }
- 优势:可根据属性类型、上下文等复杂逻辑动态调整命名,灵活性拉满,适合嵌入到自定义代码生成工具链中。
内容的提问来源于stack exchange,提问作者Rashid
相关产品推荐
相关产品推荐

