-
Notifications
You must be signed in to change notification settings - Fork 81
Description
Description
In .NET 6, ASP.NET Core added support for Delegate route handlers in addition to conventional RequestDelegate endpoints which have existed since ASP.NET Core 3.0.
In .NET 7 RC 1, we started automatically generating more API metadata for the older RequestDelegate endpoints to align the behavior of these two kinds of endpoints. In .NET 7 RC 2, we plan to revert this breaking change which will cause no API metadata to inferred for RequestDelegate endpoints again.
Version
.NET 7 RC1
Previous behavior
Before .NET 7 RC1, conventional RequestDelegate endpoints did not get added to the ApiExplorer model or the OpenApiOperation generated by WithOpenApi().
New behavior
In .NET RC 1 and RC 1 only (this is being reverted in RC 2), the RequestDelegate's MethodInfo is added to the EndpointMetadataCollection just like with Delegate route handlers causing ApiExplorer and WithOpenApi() to generate endpoint metadata for endpoints that previously were not part of the model.
This can impact third party libraries like Swashbuckle and NSwag.
See dotnet/aspnetcore#44005 for more context.
Type of breaking change
- Binary incompatible: Existing binaries may encounter a breaking change in behavior, such as failure to load/execute or different run-time behavior.
- Source incompatible: Source code may encounter a breaking change in behavior when targeting the new runtime/component/SDK, such as compile errors or different run-time behavior.
- Behavioral change: Existing code and binaries may experience different run-time behavior.
Reason for change
We were hoping that aligning the behavior of RequestDelegate and Delegate backed endpoints would reduce confusion. We've decided to walk this back though.
Recommended action
You can add a custom convention that removes the MethodInfo from the endpoint metadata or wait for RC 2 to revert this behavior. You can use a group to make it apply to multiple endpoints.
var noMetadataGroup = app.MapGroup("");
IEndpointConventionBuilder groupConventionBuilder = noMetadataGroup;
groupConventionBuilder.Add(endpointBuilder =>
{
if (endpointBuilder.Metadata.FirstOrDefault(m => m is MethodInfo) is MethodInfo method)
{
endpointBuilder.Metadata.Remove(method);
}
});
noMetadataGroup.MapGet("/", (context) => context.Response.WriteAsync("RequestDelegate endpoint."));Affected APIs
Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.Map(IEndpointRouteBuilder, RoutePattern, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.Map(IEndpointRouteBuilder, String, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapGet(IEndpointRouteBuilder, String, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapPost(IEndpointRouteBuilder, String, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapDelete(IEndpointRouteBuilder, String, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapPut(IEndpointRouteBuilder, String, RequestDelegate)Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapMethods(IEndpointRouteBuilder, String, IEnumerable<String>, RequestDelegate)