Skip to content

[Breaking change]: ApiExplorer and OpenAPI metadata is generated for RequestDelegate endpoints in RC1 *only* #493

@halter73

Description

@halter73

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)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions