Skip to content

Commit bcf4f8a

Browse files
authored
[C#] Fix oneOf derserialization with additional properties (#8057)
* fix oneOf derserializaoneOf deserialization with additonal prop * fix tests due to better handlding of additional prop
1 parent b0ecaab commit bcf4f8a

File tree

33 files changed

+647
-95
lines changed

33 files changed

+647
-95
lines changed

modules/openapi-generator/src/main/resources/csharp-netcore/AbstractOpenAPISchema.mustache

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ namespace {{packageName}}.{{modelPackage}}
2828
}
2929
};
3030

31+
/// <summary>
32+
/// Custom JSON serializer for objects with additional properties
33+
/// </summary>
34+
static public readonly JsonSerializerSettings AdditionalPropertiesSerializerSettings = new JsonSerializerSettings
35+
{
36+
// OpenAPI generated types generally hide default constructors.
37+
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
38+
MissingMemberHandling = MissingMemberHandling.Ignore,
39+
ContractResolver = new DefaultContractResolver
40+
{
41+
NamingStrategy = new CamelCaseNamingStrategy
42+
{
43+
OverrideSpecifiedNames = false
44+
}
45+
}
46+
};
47+
3148
/// <summary>
3249
/// Gets or Sets the actual instance
3350
/// </summary>

modules/openapi-generator/src/main/resources/csharp-netcore/modelOneOf.mustache

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,12 @@
112112
{
113113
{{#mappedModels}}
114114
case "{{{mappingName}}}":
115-
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{modelName}}}>(jsonString, {{classname}}.SerializerSettings));
115+
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{modelName}}}>(jsonString, {{classname}}.AdditionalPropertiesSerializerSettings));
116+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
117+
if (new{{{classname}}}.GetType().GetProperty("AdditionalProperties") == null)
118+
{
119+
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{modelName}}}>(jsonString, {{classname}}.SerializerSettings));
120+
}
116121
return new{{classname}};
117122
{{/mappedModels}}
118123
default:
@@ -128,7 +133,12 @@
128133

129134
try
130135
{
131-
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.SerializerSettings));
136+
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.AdditionalPropertiesSerializerSettings));
137+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
138+
if (new{{{classname}}}.GetType().GetProperty("AdditionalProperties") == null)
139+
{
140+
new{{classname}} = new {{classname}}(JsonConvert.DeserializeObject<{{{.}}}>(jsonString, {{classname}}.SerializerSettings));
141+
}
132142
matchedTypes.Add("{{{.}}}");
133143
match++;
134144
}

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/AbstractOpenAPISchema.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ public abstract partial class AbstractOpenAPISchema
3636
}
3737
};
3838

39+
/// <summary>
40+
/// Custom JSON serializer for objects with additional properties
41+
/// </summary>
42+
static public readonly JsonSerializerSettings AdditionalPropertiesSerializerSettings = new JsonSerializerSettings
43+
{
44+
// OpenAPI generated types generally hide default constructors.
45+
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
46+
MissingMemberHandling = MissingMemberHandling.Ignore,
47+
ContractResolver = new DefaultContractResolver
48+
{
49+
NamingStrategy = new CamelCaseNamingStrategy
50+
{
51+
OverrideSpecifiedNames = false
52+
}
53+
}
54+
};
55+
3956
/// <summary>
4057
/// Gets or Sets the actual instance
4158
/// </summary>

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/Fruit.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,12 @@ public static Fruit FromJson(string jsonString)
147147

148148
try
149149
{
150-
newFruit = new Fruit(JsonConvert.DeserializeObject<Apple>(jsonString, Fruit.SerializerSettings));
150+
newFruit = new Fruit(JsonConvert.DeserializeObject<Apple>(jsonString, Fruit.AdditionalPropertiesSerializerSettings));
151+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
152+
if (newFruit.GetType().GetProperty("AdditionalProperties") == null)
153+
{
154+
newFruit = new Fruit(JsonConvert.DeserializeObject<Apple>(jsonString, Fruit.SerializerSettings));
155+
}
151156
matchedTypes.Add("Apple");
152157
match++;
153158
}
@@ -159,7 +164,12 @@ public static Fruit FromJson(string jsonString)
159164

160165
try
161166
{
162-
newFruit = new Fruit(JsonConvert.DeserializeObject<Banana>(jsonString, Fruit.SerializerSettings));
167+
newFruit = new Fruit(JsonConvert.DeserializeObject<Banana>(jsonString, Fruit.AdditionalPropertiesSerializerSettings));
168+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
169+
if (newFruit.GetType().GetProperty("AdditionalProperties") == null)
170+
{
171+
newFruit = new Fruit(JsonConvert.DeserializeObject<Banana>(jsonString, Fruit.SerializerSettings));
172+
}
163173
matchedTypes.Add("Banana");
164174
match++;
165175
}

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/FruitReq.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,12 @@ public static FruitReq FromJson(string jsonString)
156156

157157
try
158158
{
159-
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<AppleReq>(jsonString, FruitReq.SerializerSettings));
159+
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<AppleReq>(jsonString, FruitReq.AdditionalPropertiesSerializerSettings));
160+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
161+
if (newFruitReq.GetType().GetProperty("AdditionalProperties") == null)
162+
{
163+
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<AppleReq>(jsonString, FruitReq.SerializerSettings));
164+
}
160165
matchedTypes.Add("AppleReq");
161166
match++;
162167
}
@@ -168,7 +173,12 @@ public static FruitReq FromJson(string jsonString)
168173

169174
try
170175
{
171-
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<BananaReq>(jsonString, FruitReq.SerializerSettings));
176+
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<BananaReq>(jsonString, FruitReq.AdditionalPropertiesSerializerSettings));
177+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
178+
if (newFruitReq.GetType().GetProperty("AdditionalProperties") == null)
179+
{
180+
newFruitReq = new FruitReq(JsonConvert.DeserializeObject<BananaReq>(jsonString, FruitReq.SerializerSettings));
181+
}
172182
matchedTypes.Add("BananaReq");
173183
match++;
174184
}

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/Mammal.cs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,28 @@ public static Mammal FromJson(string jsonString)
174174
switch (discriminatorValue)
175175
{
176176
case "Pig":
177-
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.SerializerSettings));
177+
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
178+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
179+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
180+
{
181+
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.SerializerSettings));
182+
}
178183
return newMammal;
179184
case "whale":
180-
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.SerializerSettings));
185+
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
186+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
187+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
188+
{
189+
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.SerializerSettings));
190+
}
181191
return newMammal;
182192
case "zebra":
183-
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.SerializerSettings));
193+
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
194+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
195+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
196+
{
197+
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.SerializerSettings));
198+
}
184199
return newMammal;
185200
default:
186201
System.Diagnostics.Debug.WriteLine(String.Format("Failed to lookup discriminator value `{0}` for Mammal. Possible values: Pig whale zebra", discriminatorValue));
@@ -192,7 +207,12 @@ public static Mammal FromJson(string jsonString)
192207

193208
try
194209
{
195-
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.SerializerSettings));
210+
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
211+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
212+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
213+
{
214+
newMammal = new Mammal(JsonConvert.DeserializeObject<Pig>(jsonString, Mammal.SerializerSettings));
215+
}
196216
matchedTypes.Add("Pig");
197217
match++;
198218
}
@@ -204,7 +224,12 @@ public static Mammal FromJson(string jsonString)
204224

205225
try
206226
{
207-
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.SerializerSettings));
227+
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
228+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
229+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
230+
{
231+
newMammal = new Mammal(JsonConvert.DeserializeObject<Whale>(jsonString, Mammal.SerializerSettings));
232+
}
208233
matchedTypes.Add("Whale");
209234
match++;
210235
}
@@ -216,7 +241,12 @@ public static Mammal FromJson(string jsonString)
216241

217242
try
218243
{
219-
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.SerializerSettings));
244+
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.AdditionalPropertiesSerializerSettings));
245+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
246+
if (newMammal.GetType().GetProperty("AdditionalProperties") == null)
247+
{
248+
newMammal = new Mammal(JsonConvert.DeserializeObject<Zebra>(jsonString, Mammal.SerializerSettings));
249+
}
220250
matchedTypes.Add("Zebra");
221251
match++;
222252
}

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/NullableShape.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,20 @@ public static NullableShape FromJson(string jsonString)
157157
switch (discriminatorValue)
158158
{
159159
case "Quadrilateral":
160-
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.SerializerSettings));
160+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.AdditionalPropertiesSerializerSettings));
161+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
162+
if (newNullableShape.GetType().GetProperty("AdditionalProperties") == null)
163+
{
164+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.SerializerSettings));
165+
}
161166
return newNullableShape;
162167
case "Triangle":
163-
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.SerializerSettings));
168+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.AdditionalPropertiesSerializerSettings));
169+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
170+
if (newNullableShape.GetType().GetProperty("AdditionalProperties") == null)
171+
{
172+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.SerializerSettings));
173+
}
164174
return newNullableShape;
165175
default:
166176
System.Diagnostics.Debug.WriteLine(String.Format("Failed to lookup discriminator value `{0}` for NullableShape. Possible values: Quadrilateral Triangle", discriminatorValue));
@@ -172,7 +182,12 @@ public static NullableShape FromJson(string jsonString)
172182

173183
try
174184
{
175-
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.SerializerSettings));
185+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.AdditionalPropertiesSerializerSettings));
186+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
187+
if (newNullableShape.GetType().GetProperty("AdditionalProperties") == null)
188+
{
189+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Quadrilateral>(jsonString, NullableShape.SerializerSettings));
190+
}
176191
matchedTypes.Add("Quadrilateral");
177192
match++;
178193
}
@@ -184,7 +199,12 @@ public static NullableShape FromJson(string jsonString)
184199

185200
try
186201
{
187-
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.SerializerSettings));
202+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.AdditionalPropertiesSerializerSettings));
203+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
204+
if (newNullableShape.GetType().GetProperty("AdditionalProperties") == null)
205+
{
206+
newNullableShape = new NullableShape(JsonConvert.DeserializeObject<Triangle>(jsonString, NullableShape.SerializerSettings));
207+
}
188208
matchedTypes.Add("Triangle");
189209
match++;
190210
}

samples/client/petstore/csharp-netcore/OpenAPIClient-net47/src/Org.OpenAPITools/Model/Pig.cs

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,20 @@ public static Pig FromJson(string jsonString)
148148
switch (discriminatorValue)
149149
{
150150
case "BasquePig":
151-
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.SerializerSettings));
151+
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.AdditionalPropertiesSerializerSettings));
152+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
153+
if (newPig.GetType().GetProperty("AdditionalProperties") == null)
154+
{
155+
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.SerializerSettings));
156+
}
152157
return newPig;
153158
case "DanishPig":
154-
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.SerializerSettings));
159+
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.AdditionalPropertiesSerializerSettings));
160+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
161+
if (newPig.GetType().GetProperty("AdditionalProperties") == null)
162+
{
163+
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.SerializerSettings));
164+
}
155165
return newPig;
156166
default:
157167
System.Diagnostics.Debug.WriteLine(String.Format("Failed to lookup discriminator value `{0}` for Pig. Possible values: BasquePig DanishPig", discriminatorValue));
@@ -163,7 +173,12 @@ public static Pig FromJson(string jsonString)
163173

164174
try
165175
{
166-
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.SerializerSettings));
176+
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.AdditionalPropertiesSerializerSettings));
177+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
178+
if (newPig.GetType().GetProperty("AdditionalProperties") == null)
179+
{
180+
newPig = new Pig(JsonConvert.DeserializeObject<BasquePig>(jsonString, Pig.SerializerSettings));
181+
}
167182
matchedTypes.Add("BasquePig");
168183
match++;
169184
}
@@ -175,7 +190,12 @@ public static Pig FromJson(string jsonString)
175190

176191
try
177192
{
178-
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.SerializerSettings));
193+
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.AdditionalPropertiesSerializerSettings));
194+
// if it does not contains "AdditionalProperties", use SerializerSettings to deserialize
195+
if (newPig.GetType().GetProperty("AdditionalProperties") == null)
196+
{
197+
newPig = new Pig(JsonConvert.DeserializeObject<DanishPig>(jsonString, Pig.SerializerSettings));
198+
}
179199
matchedTypes.Add("DanishPig");
180200
match++;
181201
}

0 commit comments

Comments
 (0)