最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Microsoft.AspNetCore.OpenAPI generates document with schema $refs to previous properties of same type instead of the base s

programmeradmin10浏览0评论

Given the following class:

public record Response
{
    public ImmutableList<TypeA>? Completes { get; init; } = null;
    public ImmutableList<TypeA>? Incompletes { get; init; } = null;

    .... // rest of class here
}

The package Microsoft.AspNetCore.OpenApi will generate the following OpenAPI spec file:

"Response": {
    "type": "object",
    "properties": {
        "Completes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        },
        "Incompletes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/#/properties/Completes/items"
            },
            "nullable": true
        }
    }

The path notation for $ref of "Incompletes" is not valid with the "#" token in the middle of the path, for the API gateway tools I use. Instead, I would like it to just refer to the actual schema, instead of a previous property of the same type, i.e:

"Response": {
    "type": "object",
    "properties": {
        "Completes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        },
        "Incompletes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        }
    }

How can this be achieved with the Microsoft.AspNetCore.OpenApi package?

In my Startup.cs, I simply added the following line:

services.AddOpenApi(ConfigureApiGen);

ConfgureApiGen does some simple things like setting document names and so forth using a document transformer.

Given the following class:

public record Response
{
    public ImmutableList<TypeA>? Completes { get; init; } = null;
    public ImmutableList<TypeA>? Incompletes { get; init; } = null;

    .... // rest of class here
}

The package Microsoft.AspNetCore.OpenApi will generate the following OpenAPI spec file:

"Response": {
    "type": "object",
    "properties": {
        "Completes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        },
        "Incompletes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/#/properties/Completes/items"
            },
            "nullable": true
        }
    }

The path notation for $ref of "Incompletes" is not valid with the "#" token in the middle of the path, for the API gateway tools I use. Instead, I would like it to just refer to the actual schema, instead of a previous property of the same type, i.e:

"Response": {
    "type": "object",
    "properties": {
        "Completes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        },
        "Incompletes": {
            "type": "array",
            "items": {
                "$ref": "#/components/schemas/TypeA"
            },
            "nullable": true
        }
    }

How can this be achieved with the Microsoft.AspNetCore.OpenApi package?

In my Startup.cs, I simply added the following line:

services.AddOpenApi(ConfigureApiGen);

ConfgureApiGen does some simple things like setting document names and so forth using a document transformer.

Share Improve this question edited Feb 5 at 13:08 Guru Stron 142k11 gold badges165 silver badges207 bronze badges asked Feb 5 at 12:29 CodingBeagleCodingBeagle 1,9503 gold badges25 silver badges53 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

As far as I can see this is a known issue which should be fixed in the upcoming .NET 9 release. From the comment by captainsafia @github:

this bug has been fixed in .NET 10 and back-ported to .NET 9. You'll find it in the next servicing release for .NET 9.

Why did this bug happen? The crux of the issue comes from the incompatibility between schemas generated by System.Text.Json, which comply strictly with the JSON Schema specification, and those expected by the OpenAPI.NET package which are a superset of JSON Schema. STJ uses relative references to capture recursive or duplicate type references. OpenAPI.NET does not recognize these as equivalent which results in duplicate schemas.

In .NET 9, we fix this by introducing logic to our custom comparers to treat relative references as equivalent to any generated type.

In .NET 10, we're upgrading to the new version of the OpenAPI.NET package which adds in built-in support for being able to resolve these relative references and detect "loop-backs" in the schema model.

I'll keep this issue open until the next .NET 9 servicing release ships. In the meantime, happy to answer any questions about the issue.

Which should be released soon:

Patches are released on the second Tuesday of a month to align with Microsoft's Update Tuesday, so the earliest would be 11th February.

As of now you can "revert" to the Swashbuckle or try using NSwag

Another issue @github

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论