Skip to content

OpenApi generates the same schema for generic types with a JsonConverterFactory. #59172

Open
@desjoerd

Description

@desjoerd

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When generating openapi containing Generic types, with a JsonConverterFactory, the same schema is generated for different types.

Given the following minimal example:

using System.Text.Json;
using System.Text.Json.Serialization;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

app.UseHttpsRedirection();
app.MapOpenApi();

app.MapGet("/", () => new ExampleModel());

app.Run();

public class GenericConverterFactory : JsonConverterFactory
{
    public override bool CanConvert(Type typeToConvert) => typeToConvert.GetGenericTypeDefinition() == typeof(GenericValue<>);

    public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options) => (JsonConverter?)Activator.CreateInstance(typeof(GenericConverter<>).MakeGenericType(typeToConvert.GetGenericArguments()[0]));
}

public class GenericConverter<T> : JsonConverter<GenericValue<T>>
{
    public override GenericValue<T> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException();

    public override void Write(Utf8JsonWriter writer, GenericValue<T> value, JsonSerializerOptions options) => throw new NotImplementedException();
}

[JsonConverter(typeof(GenericConverterFactory))]
public readonly struct GenericValue<TId>
{
    public TId Id { get; init; }
}

public class ExampleModel
{
    public GenericValue<Guid> GuidValue { get; set; }
    public GenericValue<string> StringValue { get; set; }
}

I am getting the following openapi:

{
  "openapi": "3.0.1",
  "info": {
    "title": "MinimalApi | v1",
    "version": "1.0.0"
  },
  "paths": {
    "/": {
      "get": {
        "tags": [
          "MinimalApi"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExampleModel"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ExampleModel": {
        "type": "object",
        "properties": {
          "guidValue": {
            "$ref": "#/components/schemas/GenericValueOfstring"
          },
          "stringValue": {
            "$ref": "#/components/schemas/GenericValueOfstring"
          }
        }
      },
      "GenericValueOfstring": { }
    }
  },
  "tags": [
    {
      "name": "MinimalApi"
    }
  ]
}

There is only one schema generated for the GenericValue, namely GenericValueOfstring (which is the last defined type). I was expecting GenericValueOfstring and GenericValueOfGuid.

Expected Behavior

No response

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

9.0.100

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions