Skip to content

[BUG] [CSHARP] [GENERICHOST] JsonConverter.mustache template broken for anyOf and oneOf with generic collections #23529

@laazik

Description

@laazik

{{datatypeWithEnum}}JsonConverter {{#lambda.camelcase}}{{datatypeWithEnum}}{{/lambda.camelcase}}JsonConverter = ({{datatypeWithEnum}}JsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert({{#lambda.camelcase_sanitize_param}}{{model.classname}}{{/lambda.camelcase_sanitize_param}}.{{name}}{{^required}}Option.Value{{/required}}.GetType()));

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();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions