In .NET 6, ASP.NET Core added support for Delegateroute 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.
[ ] 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.
[X] 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."));
Description
In .NET 6, ASP.NET Core added support for
Delegate
route handlers in addition to conventionalRequestDelegate
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 forRequestDelegate
endpoints again.Version
.NET 7 RC1
Previous behavior
Before .NET 7 RC1, conventional
RequestDelegate
endpoints did not get added to the ApiExplorer model or theOpenApiOperation
generated by WithOpenApi().New behavior
In .NET RC 1 and RC 1 only (this is being reverted in RC 2), the
RequestDelegate
'sMethodInfo
is added to the EndpointMetadataCollection just like withDelegate
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 https://github.com/dotnet/aspnetcore/issues/44005 for more context.
Type of breaking change
Reason for change
We were hoping that aligning the behavior of
RequestDelegate
andDelegate
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.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)