OpenAPITools / OpenAPITools/openapi-generator
[BUG] [CSHARP] [GENERICHOST] JsonConverter.mustache template broken for `anyOf` and `oneOf` with generic collections
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
For example the following yaml
'202':
description: Foo desc
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/Foo'
- type: array
items:
$ref: '#/components/schemas/Foo'
Generates following code, with incorrect < and > symbols emitted.
List<Foo>JsonConverter listltFoogtJsonConverter = (List<Foo>JsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(fooSendPost202Response.ListOption.Value.GetType()));
listltFoogtJsonConverter.WriteProperties(writer, fooSendPost202Response.ListOption.Value, jsonSerializerOptions);
GPt-5.4 and Claude proposed the following fix to the template - looks correct and generation works also correctly, but as I am no templating expert and mustache skills are also questionable, then would be great if someone takes a look into this.
{{#composedSchemas}}
{{#oneOf}}
// oneOf block
if ({{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}} != null)
{
{{#isArray}}
// isArray
JsonSerializer.Serialize(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}, jsonSerializerOptions);
return;
{{/isArray}}
{{#isMap}}
// isMap
JsonSerializer.Serialize(writer, {{#lambda.camelcase_sanitize_param}}{{classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}, jsonSerializerOptions);
return;
{{/isMap}}
}
{{/oneOf}}
{{#anyOf}}
// anyOf block
{{#isArray}}
// isArray
if ({{#lambda.joinWithAmpersand}}{{^required}}{{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}Option.IsSet {{/required}}{{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{/required}} != null{{/lambda.joinWithAmpersand}})
{
JsonSerializer.Serialize(writer, {{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}, jsonSerializerOptions);
return;
}
{{/isArray}}
{{#isMap}}
// isMap
if ({{#lambda.joinWithAmpersand}}{{^required}}{{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}Option.IsSet {{/required}}{{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{/required}} != null{{/lambda.joinWithAmpersand}})
{
JsonSerializer.Serialize(writer, {{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{#vendorExtensions.x-is-value-type}}.Value{{/vendorExtensions.x-is-value-type}}{{/required}}, jsonSerializerOptions);
return;
}
{{/isMap}}
{{/anyOf}}
{{/composedSchemas}}
{{/model.discriminator}}
writer.WriteStartObject();
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at modules/openapi-generator/src/main/resources/csharp/libraries/generichost/JsonConverter.mustache around line 398 and reproduce the issue with the provided anyOf schema. Compare the generated C# for generic collections with the expected type syntax, then verify generation no longer emits encoded angle brackets or the incorrect converter variable names.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100