Open keenjus opened 3 weeks ago
@keenjus Thanks for filing this issue, Martin! Your repro checks out for me.
I believe the hiccup here is related to the polymorphic subtype referencing the parent in the generic type argument for the collection. I'll add a test case to our suite for this and see what the fix would look like.
ComponentDtoSectionDto - does Microsoft.AspNetCore.OpenApi support custom names? I don't like the auto-generated one.
We do support customizing the names for types, but unfortunately at the moment it won't allow you to modify the name of the polymorphic type entirely (e.g. BaseType + Subtype). :/
What kind of name would you prefer to see here?
Ideally I would like derived types to use their type names, so instead of ComponentDtoSectionDto
it would be just SectionDto
(Swashbuckle does it this way when using the same polymorphic types).
Full control over generated names would also be nice, so the current name generation wouldn't need changing.
I believe the hiccup here is related to the polymorphic subtype referencing the parent in the generic type argument for the collection. I'll add a test case to our suite for this and see what the fix would look like.
Following up on this: I'm moving this out of 9.0.0 since I need to spend a little bit more time fleshing out the fix and the window for bringing changes in .NET 9 is closing soon. This will have to come in a servicing patch for 9.0.
Full control over generated names would also be nice, so the current name generation wouldn't need changing.
Other folks have asked for this so I'll open a separate API proposal for it.
@captainsafia How do I influence the naming of schemas based on the .NET type? To remove a "Dto" suffix. I can't seem to find that in the documentation. I've tried the known transformers but no luck.
I'm moving my 20+ services from NSwag.
An equivalent to this:
public class CustomSchemaNameGenerator : ISchemaNameGenerator
{
public string Generate(Type type)
{
if (type.IsGenericType)
{
return $"{type.Name.Replace("`1", string.Empty)}Of{GenerateName(type.GetGenericArguments().First())}";
}
return GenerateName(type);
}
private static string GenerateName(Type type)
{
return type.Name
.Replace("Dto", string.Empty);
//.Replace("Command", string.Empty)
//.Replace("Query", string.Empty);
}
}
@captainsafia
I dug into the source code and found that the actual name that will be used as reference id, or key, in the completed schema is stored under Annotations with the key x-schema-id
.
I can modify that like so:
options.AddSchemaTransformer(static (schema, context, ct) =>
{
const string SchemaId = "x-schema-id";
if (schema.Annotations?.TryGetValue(SchemaId, out var referenceIdObject) == true
&& referenceIdObject is string newReferenceId)
{
newReferenceId = GenerateSchemaName(context.JsonTypeInfo.Type);
schema.Annotations[SchemaId] = newReferenceId;
Console.WriteLine(newReferenceId);
}
return Task.CompletedTask;
});
The type OpenApiConstants
is not public. Otherwise, I would have used OpenApiConstants.SchemaId
.
I initially wondered why the doc.Component.Schema
wasn't set in the Document Transformer. But found out that the last step of creating the document is this special transformer OpenApiSchemaReferenceTransformer
that runs last.
Anyway, I'm starting to understand how this works. Not that different from any compiler having to keep track of references to types, members, and variables etc. 🙂
Is there an existing issue for this?
Describe the bug
Using polymorphic types and returning both the base class and derived class in separate controller actions causes OpenApi document generation to fail.
Document generation succeeds if you disable/remove
public ComponentDto GetComponent()
action in the provided example repository.Also it seems like something is wrong with the generated document (when the exception causing controller action is removed). At most I would expect two model schemas to be generated
ComponentDto
ComponentDtoSectionDto
- does Microsoft.AspNetCore.OpenApi support custom names? I don't like the auto-generated one.but it also generates a weird looking
SectionDto
schema which seems like a weird mix ofComponentDto
&SectionDto
Expected Behavior
OpenApi document generation should not fail and should generate correct schemas when using polymorphic types.
Steps To Reproduce
https://github.com/keenjus/OpenApiStuff/tree/7d736b83d4ddf5b4208580b9d265d690f082d7b4
Launch the project and navigate to http://localhost:5052/openapi/v1.json. Should fail with "ArgumentException: An item with the same key has already been added. Key: ComponentDtoSectionDto "
Exceptions (if any)
.NET Version
9.0.100-rc.1.24452.12
Anything else?
Microsoft.AspNetCore.OpenApi 9.0.0-rtm.24501.7