NSwagStudio生成C#客户端时重复创建类的问题求助
如何让NSwagStudio为重复的attributes结构只生成一个C#类?
我用NSwagStudio从OpenAPI文档生成C#客户端,功能正常,但有个问题:OpenAPI里Person、Address等对象里都有完全一样的attributes结构,NSwag却生成了上百个重复类(比如Attributes、Attributes2、Attributes372),总数超700个。
相关OpenAPI示例
{ "components": { "schemas": { "Person": { "type": "object", "properties": { "Id": { "type": "string" }, "Name": { "type": "string" }, "First Name": { "type": "string" }, "Lastname": { "type": "string" }, "attributes": { "type": "object", "properties": { "type": { "type": "string" }, "url": { "type": "string" } } } }, "description": "Account Object" }, "Address": { "type": "object", "properties": { "Id": { "type": "string" }, "Street": { "type": "string" }, "Post Code": { "type": "string" }, "City": { "type": "string" }, "Country": { "type": "string" }, "attributes": { "type": "object", "properties": { "type": { "type": "string" }, "url": { "type": "string" } } } }, "description": "Address Object" } } } }
生成的重复C#类示例
public partial class Attributes{ [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Type { get; set; } [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Url { get; set; } private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>(); [Newtonsoft.Json.JsonExtensionData] public System.Collections.Generic.IDictionary<string, object> AdditionalProperties { get { return _additionalProperties; } set { _additionalProperties = value; } } public string ToJson() { return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings()); } public static Attributes FromJson(string data) { return Newtonsoft.Json.JsonConvert.DeserializeObject<Attributes2>(data, new Newtonsoft.Json.JsonSerializerSettings()); } } public partial class Attributes2{ [Newtonsoft.Json.JsonProperty("type", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Type { get; set; } [Newtonsoft.Json.JsonProperty("url", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Url { get; set; } private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>(); [Newtonsoft.Json.JsonExtensionData] public System.Collections.Generic.IDictionary<string, object> AdditionalProperties { get { return _additionalProperties; } set { _additionalProperties = value; } } public string ToJson() { return Newtonsoft.Json.JsonConvert.SerializeObject(this, new Newtonsoft.Json.JsonSerializerSettings()); } public static Attributes2 FromJson(string data) { return Newtonsoft.Json.JsonConvert.DeserializeObject<Attributes2>(data, new Newtonsoft.Json.JsonSerializerSettings()); } }
路径部分的$ref引用
{ "/Person": { "description": "", "get": { "responses": { "200": { "description": "Status Code 200", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Person" } } } } } } } }
生成的Person类示例
public partial class Person{ [Newtonsoft.Json.JsonProperty("Id", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Id { get; set; } [Newtonsoft.Json.JsonProperty("Name", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string Name{ get; set; } [Newtonsoft.Json.JsonProperty("LastName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string LastName { get; set; } [Newtonsoft.Json.JsonProperty("FirstName", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public string FirstName { get; set; } [Newtonsoft.Json.JsonProperty("attributes", Required = Newtonsoft.Json.Required.DisallowNull, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)] public Attributes372 Attributes { get; set; } private System.Collections.Generic.IDictionary<string, object> _additionalProperties = new System.Collections.Generic.Dictionary<string, object>(); [Newtonsoft.Json.JsonExtensionData] public System.Collections.Generic.IDictionary<string, object> AdditionalProperties { get { return _additionalProperties; } set { _additionalProperties = value; } } }
解决方案
可以实现只生成一个Attributes类,有两种可行方式:
1. 修改OpenAPI文档(推荐)
把重复的attributes结构提取成独立的Schema,用$ref引用它,这样NSwag会识别为同一个类型。
修改后的OpenAPI示例:
{ "components": { "schemas": { "Attributes": { "type": "object", "properties": { "type": { "type": "string" }, "url": { "type": "string" } } }, "Person": { "type": "object", "properties": { "Id": { "type": "string" }, "Name": { "type": "string" }, "First Name": { "type": "string" }, "Lastname": { "type": "string" }, "attributes": { "$ref": "#/components/schemas/Attributes" } }, "description": "Account Object" }, "Address": { "type": "object", "properties": { "Id": { "type": "string" }, "Street": { "type": "string" }, "Post Code": { "type": "string" }, "City": { "type": "string" }, "Country": { "type": "string" }, "attributes": { "$ref": "#/components/schemas/Attributes" } }, "description": "Address Object" } } } }
这样所有用到attributes的地方都会引用同一个Schema,NSwag只会生成一个Attributes类。
2. 配置NSwagStudio的类型合并选项
如果无法修改OpenAPI文档,可在NSwagStudio里启用类型合并:
- 打开NSwagStudio,切换到CSharp Client选项卡
- 找到Type Generation部分,勾选
Merge identical types选项 - 还可以调整
Type Name Generator的设置,确保相同结构的类型生成一致的名称
注意:这个选项可能会有边缘情况,比如某些结构看似相同但实际有细微差异(比如nullable设置),需要测试验证。
内容的提问来源于stack exchange,提问作者user3644868
相关产品推荐
相关产品推荐

