dotnet / dotnet/aspnetcore

ModelEndpointDataSource not idempotent

Open
#29,146 6 comments 0 reactions 0 assignees View on GitHub
area-mvc feature-routing investigate
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.