ModelEndpointDataSource not idempotent
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 281
Description
### Describe the bug
[ModelEndpointDataSource.Endpoints.getter](https://github.com/dotnet/aspnetcore/blob/790c4dc2cf59e16e6144f7790328d563ca310533/src/Http/Routing/src/ModelEndpointDataSource.cs#L35) is not idempotent.
Since [DefaultEndpointConventionBuilder.Build()](https://github.com/dotnet/aspnetcore/blob/790c4dc2cf59e16e6144f7790328d563ca310533/src/Http/Routing/src/DefaultEndpointConventionBuilder.cs#L28) doesn't use another copy / clone of the original EndpointBuilder, if the `_conventions` is not empty, the convention will be applied one more time. Something like `endpointConventionBuilder.WithMetadata(new HttpMethodMetadata(new[] { "GET" }))` will add the repeated metadata object into that `EndpointBuilder`, and the metadata collection of last built endpoint will grow larger.
The following scenarios will make the convention collection non-empty:
- endpoints.MapMethods/MapGet/MapPost/MapPut/MapFallback/...
- endpoints.Map(...).WithMetadata(...)
A new endpoint will be created when
- Use reflection and read `IOptions.Value.EndpointDataSources.SelectMany(a => a.Endpoints)`
- The change token of `ActionEndpointDataSourceBase` is notified (which will take the last built endpoint to Match)
Maybe we should make `DefaultEndpointConventionBuilder.Build()` idempotent or the result of `ModelEndpointDataSource.Endpoints` cached.
### Further technical details
- ASP.NET Core version 3.0, 3.1, 5.0
Contributor guide
Assessment
This issue has not been assessed yet.