Closed Auros closed 3 months ago
@Auros Thanks for taking the time to craft such a great bug report! 🙇🏽
You've identified the big crux with the problem at the moment: outside of the TransformNode
API, the underlying JsonSchemaExporter
doesn't provide a way for types to describe how their schemas should be generated. The notion of a MapType
method like you mentioned has been documented before (see https://github.com/dotnet/aspnetcore/issues/56448). At the moment I'm inclined to maintain a smaller surface area for schema-related modifications in M.A.OpenAPI in favor of pushing for more customizations at the System.Text.Json level. This will make it a little bit easier to manage the implementation as we work towards OpenAPI v3.1 support which supports JsonSchema more fully. I hope that some of the underlying API improvements will come in .NET 10.
For .NET 9, I think the best place to land is to fix the issue that is causing the exception to be thrown and rely on schema tranformers to fix up the schema as needed.
Is there an existing issue for this?
Describe the bug
Using the .NET 9 version of Microsoft.AspNetCore.OpenApi (
9.0.0-rc.1.24376.4
), in the document generation process, upon encountering a non-standard type with a custom converter that serializes into a primitive JSON value (JsonTypeInfo.Kind is None), the generator will throw an exception related to System.Text.Json's schemas.Expected Behavior
When a custom type with a custom converter that serializes into a JSON primitive is detected in the schema, it should have a way to represent that type as a string or number or whatever the value is supposed to be.
Steps To Reproduce
I'm using the Ulid type as an example (serializes into a string), but here is a minimal repro.
Exceptions (if any)
.NET Version
9.0.100-rc.1.24377.5
Anything else?
I would have assumed a SchemaTransformer could have been used to override the type I wanted (like outlined in #56448), but it appears all transformers run after the initial document gets generated. The underlying schema generation process seems to rely on
JsonSchema
, which is both an internal API and only explicitly implements supports the common BCL types (primitives, string, Guid, Uri, etc.), so it can't really be overridden at the moment.I personally think an API that allows setting a custom delegate (something similar but exactly
Func<Type, OpenApiSchema?>
) and having that delegate be checked first before falling back toJsonSchema
could be an option. As far as I can tell, currently every type exposed to the schema gets run through aconverter.GetSchema()
, and if that returns null and if it's a JSON primitive, it returns the True JsonNode type instead of returning a JsonObject, thus causing the exception).