Skip to content

Commit cbc78f2

Browse files
Copilotalexaka1
andcommitted
fix: delegate enum property deserialization to JsonSerializer.Deserialize
Model-level enum property reading now delegates to the enum's own registered JsonConverter via JsonSerializer.Deserialize<EnumType>() instead of inlining reader.GetString()/GetInt32() calls. This ensures the already-fixed enum converters handle all type branching correctly. Also propagate isNumeric/isInteger/isLong/isFloat/isDouble/isDecimal flags from referenced enum models to properties in patchProperty(), so the Write path correctly uses WriteNumber vs WriteString. Co-authored-by: alexaka1 <22166651+alexaka1@users.noreply.github.com>
1 parent 2c89801 commit cbc78f2

File tree

225 files changed

+812
-1942
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

225 files changed

+812
-1942
lines changed

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractCSharpCodegen.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,16 @@ protected void patchProperty(Map<String, CodegenModel> enumRefs, CodegenModel mo
839839

840840
// We do these after updateCodegenPropertyEnum to avoid generalities that don't mesh with C#.
841841
property.isPrimitiveType = true;
842+
843+
// Propagate numeric type flags from the referenced enum model so templates
844+
// can branch on isNumeric/isInteger/isLong/isFloat/isDouble/isDecimal.
845+
property.isNumeric = refModel.isNumeric;
846+
property.isInteger = refModel.isInteger;
847+
property.isLong = refModel.isLong;
848+
property.isFloat = refModel.isFloat;
849+
property.isDouble = refModel.isDouble;
850+
property.isDecimal = refModel.isDecimal;
851+
property.isString = refModel.isString;
842852
}
843853

844854
this.patchPropertyIsInherited(model, property);

modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -225,20 +225,7 @@
225225
{{/isDateTime}}
226226
{{#isEnum}}
227227
{{^isMap}}
228-
{{#isNumeric}}
229-
{{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}} = {{>OptionProperty}}utf8JsonReader.TokenType == JsonTokenType.Null ? ({{#isInnerEnum}}{{classname}}.{{/isInnerEnum}}{{{datatypeWithEnum}}}?)null : ({{#isInnerEnum}}{{classname}}.{{/isInnerEnum}}{{{datatypeWithEnum}}})utf8JsonReader.Get{{#vendorExtensions.x-unsigned}}U{{/vendorExtensions.x-unsigned}}Int32());
230-
{{/isNumeric}}
231-
{{^isNumeric}}
232-
string{{nrt?}} {{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}}RawValue = utf8JsonReader.GetString();
233-
{{^isInnerEnum}}
234-
if ({{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}}RawValue != null)
235-
{{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}} = {{>OptionProperty}}{{{datatypeWithEnum}}}ValueConverter.FromStringOrDefault({{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}}RawValue));
236-
{{/isInnerEnum}}
237-
{{#isInnerEnum}}
238-
if ({{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}}RawValue != null)
239-
{{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}} = {{>OptionProperty}}{{classname}}.{{{datatypeWithEnum}}}FromStringOrDefault({{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}}RawValue));
240-
{{/isInnerEnum}}
241-
{{/isNumeric}}
228+
{{#lambda.camelcase_sanitize_param}}{{name}}{{/lambda.camelcase_sanitize_param}} = {{>OptionProperty}}JsonSerializer.Deserialize<{{#isInnerEnum}}{{classname}}.{{/isInnerEnum}}{{{datatypeWithEnum}}}{{#isNullable}}?{{/isNullable}}>(ref utf8JsonReader, jsonSerializerOptions));
242229
{{/isMap}}
243230
{{/isEnum}}
244231
{{#isUuid}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/csharpnetcore/CSharpClientCodegenTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,5 +337,24 @@ public void testIntegerEnumJsonConverterUsesNumericOperations() throws IOExcepti
337337
"writer.WriteStringValue(",
338338
"return (double) value"
339339
);
340+
341+
// Verify model with enum properties uses JsonSerializer.Deserialize for enum props
342+
File modelFile = files.get(Paths
343+
.get(output.getAbsolutePath(), "src", "Org.OpenAPITools", "Model", "ModelWithEnumProperties.cs")
344+
.toString()
345+
);
346+
assertNotNull(modelFile, "Could not find file for model: ModelWithEnumProperties");
347+
assertFileContains(modelFile.toPath(),
348+
"JsonSerializer.Deserialize<IntegerEnum",
349+
"JsonSerializer.Deserialize<LongEnum",
350+
"JsonSerializer.Deserialize<DoubleEnum"
351+
);
352+
// Enum property values should NOT be read inline with Get* methods;
353+
// only the JSON property name key uses GetString, not the enum values
354+
assertFileNotContains(modelFile.toPath(),
355+
"utf8JsonReader.GetInt32()",
356+
"utf8JsonReader.GetInt64()",
357+
"utf8JsonReader.GetDouble()"
358+
);
340359
}
341360
}

modules/openapi-generator/src/test/resources/3_0/csharp/integer-enum.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,12 @@ components:
4141
- -1.2
4242
type: number
4343
format: double
44+
ModelWithEnumProperties:
45+
type: object
46+
properties:
47+
intEnum:
48+
$ref: '#/components/schemas/IntegerEnum'
49+
longEnum:
50+
$ref: '#/components/schemas/LongEnum'
51+
doubleEnum:
52+
$ref: '#/components/schemas/DoubleEnum'

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/ChildCat.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,7 @@ public override ChildCat Read(ref Utf8JsonReader utf8JsonReader, Type typeToConv
119119
switch (localVarJsonPropertyName)
120120
{
121121
case "pet_type":
122-
string petTypeRawValue = utf8JsonReader.GetString();
123-
if (petTypeRawValue != null)
124-
petType = new Option<ChildCatAllOfPetType?>(ChildCatAllOfPetTypeValueConverter.FromStringOrDefault(petTypeRawValue));
122+
petType = new Option<ChildCatAllOfPetType?>(JsonSerializer.Deserialize<ChildCatAllOfPetType>(ref utf8JsonReader, jsonSerializerOptions));
125123
break;
126124
case "name":
127125
name = new Option<string>(utf8JsonReader.GetString());

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/CopyActivity.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,7 @@ public override CopyActivity Read(ref Utf8JsonReader utf8JsonReader, Type typeTo
115115
copyActivitytt = new Option<string>(utf8JsonReader.GetString());
116116
break;
117117
case "$schema":
118-
string schemaRawValue = utf8JsonReader.GetString();
119-
if (schemaRawValue != null)
120-
schema = new Option<CopyActivityAllOfSchema?>(CopyActivityAllOfSchemaValueConverter.FromStringOrDefault(schemaRawValue));
118+
schema = new Option<CopyActivityAllOfSchema?>(JsonSerializer.Deserialize<CopyActivityAllOfSchema>(ref utf8JsonReader, jsonSerializerOptions));
121119
break;
122120
default:
123121
break;

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/Descendant1.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,7 @@ public override Descendant1 Read(ref Utf8JsonReader utf8JsonReader, Type typeToC
112112
descendantName = new Option<string>(utf8JsonReader.GetString());
113113
break;
114114
case "objectType":
115-
string objectTypeRawValue = utf8JsonReader.GetString();
116-
if (objectTypeRawValue != null)
117-
objectType = new Option<TestDescendantsObjectType?>(TestDescendantsObjectTypeValueConverter.FromStringOrDefault(objectTypeRawValue));
115+
objectType = new Option<TestDescendantsObjectType?>(JsonSerializer.Deserialize<TestDescendantsObjectType>(ref utf8JsonReader, jsonSerializerOptions));
118116
break;
119117
default:
120118
break;

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/Descendant2.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,7 @@ public override Descendant2 Read(ref Utf8JsonReader utf8JsonReader, Type typeToC
112112
confidentiality = new Option<string>(utf8JsonReader.GetString());
113113
break;
114114
case "objectType":
115-
string objectTypeRawValue = utf8JsonReader.GetString();
116-
if (objectTypeRawValue != null)
117-
objectType = new Option<TestDescendantsObjectType?>(TestDescendantsObjectTypeValueConverter.FromStringOrDefault(objectTypeRawValue));
115+
objectType = new Option<TestDescendantsObjectType?>(JsonSerializer.Deserialize<TestDescendantsObjectType>(ref utf8JsonReader, jsonSerializerOptions));
118116
break;
119117
default:
120118
break;

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/EnumArrays.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,7 @@ public override EnumArrays Read(ref Utf8JsonReader utf8JsonReader, Type typeToCo
146146
arrayEnum = new Option<List<EnumArraysArrayEnumInner>>(JsonSerializer.Deserialize<List<EnumArraysArrayEnumInner>>(ref utf8JsonReader, jsonSerializerOptions));
147147
break;
148148
case "just_symbol":
149-
string justSymbolRawValue = utf8JsonReader.GetString();
150-
if (justSymbolRawValue != null)
151-
justSymbol = new Option<EnumArraysJustSymbol?>(EnumArraysJustSymbolValueConverter.FromStringOrDefault(justSymbolRawValue));
149+
justSymbol = new Option<EnumArraysJustSymbol?>(JsonSerializer.Deserialize<EnumArraysJustSymbol>(ref utf8JsonReader, jsonSerializerOptions));
152150
break;
153151
default:
154152
break;

samples/client/petstore/csharp/generichost/net10/FormModels/src/Org.OpenAPITools/Model/EnumTest.cs

Lines changed: 18 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -255,49 +255,31 @@ public override EnumTest Read(ref Utf8JsonReader utf8JsonReader, Type typeToConv
255255
switch (localVarJsonPropertyName)
256256
{
257257
case "enum_string_required":
258-
string enumStringRequiredRawValue = utf8JsonReader.GetString();
259-
if (enumStringRequiredRawValue != null)
260-
enumStringRequired = new Option<EnumTestEnumString?>(EnumTestEnumStringValueConverter.FromStringOrDefault(enumStringRequiredRawValue));
258+
enumStringRequired = new Option<EnumTestEnumString?>(JsonSerializer.Deserialize<EnumTestEnumString>(ref utf8JsonReader, jsonSerializerOptions));
261259
break;
262260
case "enum_integer":
263-
string enumIntegerRawValue = utf8JsonReader.GetString();
264-
if (enumIntegerRawValue != null)
265-
enumInteger = new Option<EnumTestEnumInteger?>(EnumTestEnumIntegerValueConverter.FromStringOrDefault(enumIntegerRawValue));
261+
enumInteger = new Option<EnumTestEnumInteger?>(JsonSerializer.Deserialize<EnumTestEnumInteger>(ref utf8JsonReader, jsonSerializerOptions));
266262
break;
267263
case "enum_integer_only":
268-
string enumIntegerOnlyRawValue = utf8JsonReader.GetString();
269-
if (enumIntegerOnlyRawValue != null)
270-
enumIntegerOnly = new Option<EnumTestEnumIntegerOnly?>(EnumTestEnumIntegerOnlyValueConverter.FromStringOrDefault(enumIntegerOnlyRawValue));
264+
enumIntegerOnly = new Option<EnumTestEnumIntegerOnly?>(JsonSerializer.Deserialize<EnumTestEnumIntegerOnly>(ref utf8JsonReader, jsonSerializerOptions));
271265
break;
272266
case "enum_number":
273-
string enumNumberRawValue = utf8JsonReader.GetString();
274-
if (enumNumberRawValue != null)
275-
enumNumber = new Option<TestEnumParametersEnumQueryDoubleParameter?>(TestEnumParametersEnumQueryDoubleParameterValueConverter.FromStringOrDefault(enumNumberRawValue));
267+
enumNumber = new Option<TestEnumParametersEnumQueryDoubleParameter?>(JsonSerializer.Deserialize<TestEnumParametersEnumQueryDoubleParameter>(ref utf8JsonReader, jsonSerializerOptions));
276268
break;
277269
case "enum_string":
278-
string enumStringRawValue = utf8JsonReader.GetString();
279-
if (enumStringRawValue != null)
280-
enumString = new Option<EnumTestEnumString?>(EnumTestEnumStringValueConverter.FromStringOrDefault(enumStringRawValue));
270+
enumString = new Option<EnumTestEnumString?>(JsonSerializer.Deserialize<EnumTestEnumString>(ref utf8JsonReader, jsonSerializerOptions));
281271
break;
282272
case "outerEnum":
283-
string outerEnumRawValue = utf8JsonReader.GetString();
284-
if (outerEnumRawValue != null)
285-
outerEnum = new Option<OuterEnum?>(OuterEnumValueConverter.FromStringOrDefault(outerEnumRawValue));
273+
outerEnum = new Option<OuterEnum?>(JsonSerializer.Deserialize<OuterEnum?>(ref utf8JsonReader, jsonSerializerOptions));
286274
break;
287275
case "outerEnumDefaultValue":
288-
string outerEnumDefaultValueRawValue = utf8JsonReader.GetString();
289-
if (outerEnumDefaultValueRawValue != null)
290-
outerEnumDefaultValue = new Option<OuterEnumDefaultValue?>(OuterEnumDefaultValueValueConverter.FromStringOrDefault(outerEnumDefaultValueRawValue));
276+
outerEnumDefaultValue = new Option<OuterEnumDefaultValue?>(JsonSerializer.Deserialize<OuterEnumDefaultValue>(ref utf8JsonReader, jsonSerializerOptions));
291277
break;
292278
case "outerEnumInteger":
293-
string outerEnumIntegerRawValue = utf8JsonReader.GetString();
294-
if (outerEnumIntegerRawValue != null)
295-
outerEnumInteger = new Option<OuterEnumInteger?>(OuterEnumIntegerValueConverter.FromStringOrDefault(outerEnumIntegerRawValue));
279+
outerEnumInteger = new Option<OuterEnumInteger?>(JsonSerializer.Deserialize<OuterEnumInteger>(ref utf8JsonReader, jsonSerializerOptions));
296280
break;
297281
case "outerEnumIntegerDefaultValue":
298-
string outerEnumIntegerDefaultValueRawValue = utf8JsonReader.GetString();
299-
if (outerEnumIntegerDefaultValueRawValue != null)
300-
outerEnumIntegerDefaultValue = new Option<OuterEnumIntegerDefaultValue?>(OuterEnumIntegerDefaultValueValueConverter.FromStringOrDefault(outerEnumIntegerDefaultValueRawValue));
282+
outerEnumIntegerDefaultValue = new Option<OuterEnumIntegerDefaultValue?>(JsonSerializer.Deserialize<OuterEnumIntegerDefaultValue>(ref utf8JsonReader, jsonSerializerOptions));
301283
break;
302284
default:
303285
break;
@@ -363,20 +345,14 @@ public void WriteProperties(Utf8JsonWriter writer, EnumTest enumTest, JsonSerial
363345
writer.WriteString("enum_string_required", enumStringRequiredRawValue);
364346

365347
if (enumTest.EnumIntegerOption.IsSet)
366-
{
367-
var enumIntegerRawValue = EnumTestEnumIntegerValueConverter.ToJsonValue(enumTest.EnumInteger.Value);
368-
writer.WriteNumber("enum_integer", enumIntegerRawValue);
369-
}
348+
writer.WriteNumber("enum_integer", EnumTestEnumIntegerToJsonValue(enumTest.EnumIntegerOption.Value.Value));
349+
370350
if (enumTest.EnumIntegerOnlyOption.IsSet)
371-
{
372-
var enumIntegerOnlyRawValue = EnumTestEnumIntegerOnlyValueConverter.ToJsonValue(enumTest.EnumIntegerOnly.Value);
373-
writer.WriteNumber("enum_integer_only", enumIntegerOnlyRawValue);
374-
}
351+
writer.WriteNumber("enum_integer_only", EnumTestEnumIntegerOnlyToJsonValue(enumTest.EnumIntegerOnlyOption.Value.Value));
352+
375353
if (enumTest.EnumNumberOption.IsSet)
376-
{
377-
var enumNumberRawValue = TestEnumParametersEnumQueryDoubleParameterValueConverter.ToJsonValue(enumTest.EnumNumber.Value);
378-
writer.WriteNumber("enum_number", enumNumberRawValue);
379-
}
354+
writer.WriteNumber("enum_number", TestEnumParametersEnumQueryDoubleParameterToJsonValue(enumTest.EnumNumberOption.Value.Value));
355+
380356
if (enumTest.EnumStringOption.IsSet)
381357
{
382358
var enumStringRawValue = EnumTestEnumStringValueConverter.ToJsonValue(enumTest.EnumString.Value);
@@ -396,15 +372,10 @@ public void WriteProperties(Utf8JsonWriter writer, EnumTest enumTest, JsonSerial
396372
writer.WriteString("outerEnumDefaultValue", outerEnumDefaultValueRawValue);
397373
}
398374
if (enumTest.OuterEnumIntegerOption.IsSet)
399-
{
400-
var outerEnumIntegerRawValue = OuterEnumIntegerValueConverter.ToJsonValue(enumTest.OuterEnumInteger.Value);
401-
writer.WriteNumber("outerEnumInteger", outerEnumIntegerRawValue);
402-
}
375+
writer.WriteNumber("outerEnumInteger", OuterEnumIntegerToJsonValue(enumTest.OuterEnumIntegerOption.Value.Value));
376+
403377
if (enumTest.OuterEnumIntegerDefaultValueOption.IsSet)
404-
{
405-
var outerEnumIntegerDefaultValueRawValue = OuterEnumIntegerDefaultValueValueConverter.ToJsonValue(enumTest.OuterEnumIntegerDefaultValue.Value);
406-
writer.WriteNumber("outerEnumIntegerDefaultValue", outerEnumIntegerDefaultValueRawValue);
407-
}
378+
writer.WriteNumber("outerEnumIntegerDefaultValue", OuterEnumIntegerDefaultValueToJsonValue(enumTest.OuterEnumIntegerDefaultValueOption.Value.Value));
408379
}
409380
}
410381
}

0 commit comments

Comments
 (0)