Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microsoft.AspNetCore.OpenApi generates a class that does not exist but is like a other class with a number added to the end of the name #59677

Open
1 task done
SMAH1 opened this issue Jan 1, 2025 · 0 comments
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-openapi

Comments

@SMAH1
Copy link

SMAH1 commented Jan 1, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have asp dotnet 9.0 project.

I use Microsoft.AspNetCore.OpenApi to generate OpenAPI and use Scalar and SwaggerUI to show it.
my project file is

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <InvariantGlobalization>true</InvariantGlobalization>
    <PublishAot>true</PublishAot>
	<OpenApiDocumentsDirectory>./</OpenApiDocumentsDirectory>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
    <PackageReference Include="Scalar.AspNetCore" Version="1.2.55" />
    <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="7.2.0" />
  </ItemGroup>

</Project>

and there are Monitoring api and class like this:

using System.Net;

namespace WebApiAotTest;

public class MonitoringItem
{
    public string[] Name { get; set; } = null!;
    public int value { get; set; }
}

public class MonitoringRoot
{
    public MonitoringItem Item1 { get; set; } = null!;
    public MonitoringItem Item2 { get; set; } = null!;
}

public static class MonitoringExtension
{
    public static void MonitoringApi(this WebApplication app)
    {
        var monitoringApi = app.MapGroup("/monitoring");

        monitoringApi.MapGet("/", () => new MonitoringRoot() )
            .Produces<MonitoringRoot>((int)HttpStatusCode.OK)
            .WithTags("Monitoring")
            .WithSummary("Get Monitoring")
            .WithDescription("This endpoint returns Monitoring data.");
    }
}

The API return MonitoringRoot that has multi MonitoringItem.

and program.cs is:

using Microsoft.AspNetCore.OpenApi;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;
using System.Text.Json.Serialization;
using WebApiAotTest;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.AddOpenApi(options =>
{
    options.AddDocumentTransformer((document, context, cancellationToken) =>
    {
        document.Info.Contact = new OpenApiContact
        {
            Name = "Contoso Support",
            Email = "[email protected]"
        };
        return Task.CompletedTask;
    });

    options.CreateSchemaReferenceId = (type) => type.Type.IsEnum ? null : OpenApiOptions.CreateDefaultSchemaReferenceId(type);
});

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
});

var app = builder.Build();

app.MapOpenApi("/openapi/v1/my.json");
app.UseSwaggerUI(opt =>
{
    opt.SwaggerEndpoint("/openapi/v1/my.json", "MyApi");
});
app.MapScalarApiReference(opt =>
{
    opt
        .WithTitle("MyApi")
        .WithOpenApiRoutePattern("/openapi/v1/{documentName}.json")
        .WithEndpointPrefix("/openapi/{documentName}")
        ;
});

app.MonitoringApi();
app.Run();

[JsonSerializable(typeof(MonitoringRoot))]
internal partial class AppJsonSerializerContext : JsonSerializerContext
{

}

API works OK. but when I see swagger, there is wrong data!

Image

and (??!!!!):

Image

also original json has wrong:

{
  "openapi": "3.0.1",
  "info": {
    "title": "WebApiAotTest | v1",
    "contact": {
      "name": "Contoso Support",
      "email": "[email protected]"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "http://localhost:5090"
    }
  ],
  "paths": {
    "/monitoring": {
      "get": {
        "tags": [
          "Monitoring"
        ],
        "summary": "Get Monitoring",
        "description": "This endpoint returns Monitoring data.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MonitoringRoot"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "MonitoringItem": {
        "type": "object",
        "properties": {
          "name": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "value": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MonitoringItem2": {
        "type": "object",
        "properties": {
          "name": {
            "$ref": "#/components/schemas/#/properties/item1/properties/name"
          },
          "value": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "MonitoringRoot": {
        "type": "object",
        "properties": {
          "item1": {
            "$ref": "#/components/schemas/MonitoringItem"
          },
          "item2": {
            "$ref": "#/components/schemas/MonitoringItem2"
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Monitoring"
    }
  ]
}

There is MonitoringItem2 is json (generated by OpenAPI) but there is not in my code.

NOTE: MonitoringItem2 is exactly like MonitoringItem.
NOTE: If add Item3, Item4 , ... to MonitoringRoot, generate MonitoringItem3, MonitoringItem3, .... .
NOTE: I checked and found that the below code was causing this problem:

// in MonitoringItem
public string[] Name { get; set; }

so I remove array, everything is OK! like this:

public class MonitoringItem
{
    public string Name { get; set; } = null!;
    public int value { get; set; }
}

Expected Behavior

No generate extra data and I see:

Image

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

9.0.100

Anything else?

I use Microsoft Visual Studio Community 2022 (64-bit) Version 17.12.2 in windows 10 22H2.

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Jan 1, 2025
@martincostello martincostello added feature-openapi area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed NativeAOT area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Jan 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc feature-openapi
Projects
None yet
Development

No branches or pull requests

2 participants