New endpoints exposed by OpenAPI documentation compared to before ASP.NET Core 7 RC1
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
After updating an application from ASP.NET Core 7 preview 7 to RC1 some integration tests we have for our OpenAPI contracts started to fail because a new endpoint appeared in the description that wasn’t previously there.
Investigation lead to the internals of a NuGet package consumed by the application exposing an endpoint via a middleware using MapGet(string, RequestDelegate)
. This package targets netcoreapp3.1
so predates Minimal APIs and other new routing features.
Updating the NuGet package to add the metadata to hide the endpoint from API Explorer did not result in the endpoint being suppressed from the OpenAPI document.
I’m not sure if this is really an issue, but given that without updating the library to target net6.0
so that ExcludeFromDescriptionAttribute
can be added to the metadata, there doesn’t seem to be a way to suppress the endpoint that wasn’t there before without writing new code to filter the generated OpenAPI document.
In our case, we can update our own library to ensure it is hidden by adding a net6.0
target, but there might be other similar libraries out in the wider ecosystem that will start appearing in OpenAPI specs unexpectedly when an application is updated to .NET 7 which users do not have immediate control over.
Expected Behavior
Either:
- The endpoint is not added to the OpenAPI metadata;
- The endpoint is hidden by the use of
new ApiExplorerSettingsAttribute() { IgnoreApi = true }
on its metadata.
Steps To Reproduce
Compile and run the application below and navigate to the /swagger/v1/swagger.json
endpoint.
Targeting net7.0
, the endpoint will return the following JSON:
{
"openapi": "3.0.1",
"info": {
"title": "API",
"version": "v1"
},
"paths": {
"/metrics": {
"get": {
"tags": [
"MetricServerMiddleware"
],
"responses": {
"200": {
"description": "Success"
}
}
}
}
},
"components": { }
}
Targeting net6.0
, the endpoint will return the following JSON:
{
"openapi": "3.0.1",
"info": {
"title": "API",
"version": "v1"
},
"paths": { },
"components": { }
}
App.csproj
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>App</RootNamespace>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="prometheus-net.AspNetCore" Version="6.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
</ItemGroup>
</Project>
Program.cs
using Microsoft.AspNetCore.Mvc;
using Prometheus;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new() { Title = "API", Version = "v1" });
});
var app = builder.Build();
app.UseSwagger();
MapPrometheus(app);
app.Run();
static IEndpointRouteBuilder MapPrometheus(IEndpointRouteBuilder endpoints, string pattern = "/metrics")
{
var requestDelegate = endpoints
.CreateApplicationBuilder()
.UseMiddleware<MetricServerMiddleware>(new MetricServerMiddleware.Settings() { Registry = null })
.Build();
endpoints
.MapGet(pattern, requestDelegate)
.Add((endpoint) =>
{
endpoint.Metadata.Add(new ApiExplorerSettingsAttribute() { IgnoreApi = true });
});
return endpoints;
}
Exceptions (if any)
None.
.NET Version
7.0.100-rc.1.22431.12
Anything else?
No response
Issue Analytics
- State:
- Created a year ago
- Comments:5 (4 by maintainers)
OK, I did some digging into this and was able to find the source of the regression. So, whether or not an endpoint is registered into the API description provider (and consequently added to an OpenAPI definition) depends on 3 things:
MethodInfo
in the endpoint’s metadata that we can use to derive information about parameters/responsesHttpMethodMetadata
indicating it’s a valid HTTP endpointExcludeFromDescription
item in the endpoint’s metadataAs it turns out, the first bullet is what’s biting us here. I observed that the major delta between preview7 and RC1 was that the
/metric
endpoint registered above did haveMethodInfo
populated in RC1 but not in preview7. The underlying reason is because of a change that we made in https://github.com/dotnet/aspnetcore/commit/5eb02a4af095998acc4b83008a751af2fd1f879d. We now unconditionally addMethodInfo
to endpoint metadata regardless of whether or not it followed the route handler codepath, resulting in this unintended behavior in OpenAPI.Closing this as we’ve merged a fix targeted for release in .NET 7 RC2.