From f6aa83f0d96657d7cf2323c44765bbf2b42d3804 Mon Sep 17 00:00:00 2001 From: madhu <134006164+madhu1218@users.noreply.github.com> Date: Mon, 10 Aug 2026 21:15:46 -0400 Subject: [PATCH 1/2] fix(csharp): serialize oneOf referenced models in generichost --- .../generichost/JsonConverter.mustache | 32 +++++++++++++++++ .../Org.OpenAPITools.Test/Model/FruitTests.cs | 36 +++++++++++++++++++ .../OneOf/src/Org.OpenAPITools/Model/Fruit.cs | 17 +++++++++ 3 files changed, 85 insertions(+) diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache index 7948f79dbf7c..120f4dc0acd2 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache @@ -376,7 +376,39 @@ {{/children}} {{/discriminator}} + {{^model.discriminator}} + {{#composedSchemas}} + {{#oneOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{#isPrimitiveType}} + if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}} != null) + { + JsonSerializer.Serialize(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}, jsonSerializerOptions); + return; + } + + {{/isPrimitiveType}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/oneOf}} + {{/composedSchemas}} + {{/model.discriminator}} writer.WriteStartObject(); + {{^model.discriminator}} + {{#composedSchemas}} + {{#oneOf}} + {{^vendorExtensions.x-duplicated-data-type}} + {{^isPrimitiveType}} + if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}} != null) + { + {{baseType}}JsonConverter {{#lambda.camelcase_sanitize_param}}{{baseType}}JsonConverter{{/lambda.camelcase_sanitize_param}} = ({{baseType}}JsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}.GetType())); + {{#lambda.camelcase_sanitize_param}}{{baseType}}JsonConverter{{/lambda.camelcase_sanitize_param}}.WriteProperties(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}, jsonSerializerOptions); + } + + {{/isPrimitiveType}} + {{/vendorExtensions.x-duplicated-data-type}} + {{/oneOf}} + {{/composedSchemas}} + {{/model.discriminator}} {{#model.discriminator}} {{#model.hasDiscriminatorWithNonEmptyMapping}} diff --git a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools.Test/Model/FruitTests.cs b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools.Test/Model/FruitTests.cs index a6607ae5d56d..8eb2a2d59126 100644 --- a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools.Test/Model/FruitTests.cs +++ b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools.Test/Model/FruitTests.cs @@ -17,6 +17,7 @@ using Org.OpenAPITools.Model; using Org.OpenAPITools.Client; using System.Reflection; +using System.Text.Json; namespace Org.OpenAPITools.Test.Model { @@ -61,5 +62,40 @@ public void ColorTest() { // TODO unit test for the property 'Color' } + + [Fact] + public void SerializeOneOfReferencedObject() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new AppleJsonConverter()); + options.Converters.Add(new BananaJsonConverter()); + options.Converters.Add(new FruitJsonConverter()); + options.Converters.Add(new OrangeJsonConverter()); + + Fruit fruit = new Fruit(new Apple("red")); + + string json = JsonSerializer.Serialize(fruit, options); + + Assert.Equal("{\"kind\":\"red\"}", json); + } + + [Fact] + public void SerializeOneOfReferencedObjectWithSiblingProperty() + { + var options = new JsonSerializerOptions(); + options.Converters.Add(new AppleJsonConverter()); + options.Converters.Add(new BananaJsonConverter()); + options.Converters.Add(new FruitJsonConverter()); + options.Converters.Add(new OrangeJsonConverter()); + + Fruit fruit = new Fruit( + new Apple("red"), + new Option("green") + ); + + string json = JsonSerializer.Serialize(fruit, options); + + Assert.Equal("{\"kind\":\"red\",\"color\":\"green\"}", json); + } } } diff --git a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs index b122efb51e3d..c0510540b7ff 100644 --- a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs +++ b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs @@ -237,6 +237,23 @@ public override Fruit Read(ref Utf8JsonReader utf8JsonReader, Type typeToConvert public override void Write(Utf8JsonWriter writer, Fruit fruit, JsonSerializerOptions jsonSerializerOptions) { writer.WriteStartObject(); + if (fruit.Apple != null) + { + AppleJsonConverter appleJsonConverter = (AppleJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Apple.GetType())); + appleJsonConverter.WriteProperties(writer, fruit.Apple, jsonSerializerOptions); + } + + if (fruit.Banana != null) + { + BananaJsonConverter bananaJsonConverter = (BananaJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Banana.GetType())); + bananaJsonConverter.WriteProperties(writer, fruit.Banana, jsonSerializerOptions); + } + + if (fruit.Orange != null) + { + OrangeJsonConverter orangeJsonConverter = (OrangeJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Orange.GetType())); + orangeJsonConverter.WriteProperties(writer, fruit.Orange, jsonSerializerOptions); + } WriteProperties(writer, fruit, jsonSerializerOptions); writer.WriteEndObject(); From e55db642dddd92f80f755fafc92fb972c198b85c Mon Sep 17 00:00:00 2001 From: madhu <134006164+madhu1218@users.noreply.github.com> Date: Mon, 10 Aug 2026 23:48:51 -0400 Subject: [PATCH 2/2] fix(csharp): handle generichost oneOf converter edge cases --- .../csharp/libraries/generichost/JsonConverter.mustache | 8 +++++--- .../net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache index 120f4dc0acd2..cff653bf3c39 100644 --- a/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache @@ -397,14 +397,16 @@ {{#composedSchemas}} {{#oneOf}} {{^vendorExtensions.x-duplicated-data-type}} - {{^isPrimitiveType}} + {{#isModel}} + {{^isContainer}} if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}} != null) { - {{baseType}}JsonConverter {{#lambda.camelcase_sanitize_param}}{{baseType}}JsonConverter{{/lambda.camelcase_sanitize_param}} = ({{baseType}}JsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}.GetType())); + {{baseType}}JsonConverter {{#lambda.camelcase_sanitize_param}}{{baseType}}JsonConverter{{/lambda.camelcase_sanitize_param}} = new {{baseType}}JsonConverter(); {{#lambda.camelcase_sanitize_param}}{{baseType}}JsonConverter{{/lambda.camelcase_sanitize_param}}.WriteProperties(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}, jsonSerializerOptions); } - {{/isPrimitiveType}} + {{/isContainer}} + {{/isModel}} {{/vendorExtensions.x-duplicated-data-type}} {{/oneOf}} {{/composedSchemas}} diff --git a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs index c0510540b7ff..61cd204f6dba 100644 --- a/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs +++ b/samples/client/petstore/csharp/generichost/net8/OneOf/src/Org.OpenAPITools/Model/Fruit.cs @@ -239,19 +239,19 @@ public override void Write(Utf8JsonWriter writer, Fruit fruit, JsonSerializerOpt writer.WriteStartObject(); if (fruit.Apple != null) { - AppleJsonConverter appleJsonConverter = (AppleJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Apple.GetType())); + AppleJsonConverter appleJsonConverter = new AppleJsonConverter(); appleJsonConverter.WriteProperties(writer, fruit.Apple, jsonSerializerOptions); } if (fruit.Banana != null) { - BananaJsonConverter bananaJsonConverter = (BananaJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Banana.GetType())); + BananaJsonConverter bananaJsonConverter = new BananaJsonConverter(); bananaJsonConverter.WriteProperties(writer, fruit.Banana, jsonSerializerOptions); } if (fruit.Orange != null) { - OrangeJsonConverter orangeJsonConverter = (OrangeJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fruit.Orange.GetType())); + OrangeJsonConverter orangeJsonConverter = new OrangeJsonConverter(); orangeJsonConverter.WriteProperties(writer, fruit.Orange, jsonSerializerOptions); }