-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
Describe the bug
When inspecting endpoints with EndpointDataSource, for example in an IApiDescriptionProvider, some of the metadata on RouteEndpoint instances is duplicated. As shown in the screenshot below, there are two duplicated HTTP method metadata items.
Tracing through the code, this appears to be caused by a number of factors that together contribute to the routing endpoint conventions for an endpoint builder being run multiple times. The screenshot below shows the HTTP method metadata being added to the endpoint builder a second time.
The contributing factors to this issue appear to be:
- There are two
CompositeEndpointDataSourceinstances created by the application:_endpointDataSource = new CompositeEndpointDataSource(endpointRouteBuilder.DataSources); aspnetcore/src/Http/Routing/src/DependencyInjection/RoutingServiceCollectionExtensions.cs
Line 65 in 5577c0d
return new CompositeEndpointDataSource(dataSources); - Each
CompositeEndpointDataSourceenumerates theEndpointsproperty of each underlying endpoint data source once:_endpoints = _dataSources.SelectMany(d => d.Endpoints).ToArray(); ModelEndpointDataSourcecallsBuild()on each convention builder each time theEndpointsproperty is accessedpublic override IReadOnlyList<Endpoint> Endpoints => _endpointConventionBuilders.Select(e => e.Build()).ToArray(); - Each call to
Build()runs the convention action(s):aspnetcore/src/Http/Routing/src/DefaultEndpointConventionBuilder.cs
Lines 30 to 33 in 5577c0d
foreach (var convention in _conventions) { convention(EndpointBuilder); } - The conventions may mutate the endpoint builder's state multiple times:
aspnetcore/src/Http/Routing/src/Builder/RoutingEndpointConventionBuilderExtensions.cs
Lines 111 to 117 in 5577c0d
builder.Add(b => { foreach (var item in items) { b.Metadata.Add(item); } });
The net result is that every time the Endpoints property of an ModelEndpointDataSource is accessed, the number of Metadata items on a route endpoint increases by the number of conventions configured.
Below is an example of four duplicate metadata items in a sample application:
To Reproduce
To reproduce this issue, edit this test to have the following code:
app.MapGet("/json", (IApiDescriptionGroupCollectionProvider provider) =>
{
if (provider.ApiDescriptionGroups is not null)
{
// Used to inspect and debug ApiDescriptionGroups
}
return Json(new Person("John", 42));
});Then debug the JsonResult_Works() test with a breakpoint set here:
| foreach (var httpMethod in httpMethodMetadata.HttpMethods) |
Inspecting routeEndpoint.Metadata with the debugger will show the duplicated metadata as shown in the preceding screenshots.
Further technical details
- ASP.NET Core version
6.0.0-preview.7.21357.1 - .NET Core SDK
6.0.100-preview.7.21357.57 - Visual Studio 2022 17.0.0 Preview 1.1


