Skip to content

Microsoft.AspNetCore.OpenApi: The route template cannot start with a '~' character #64395

@dp-sgr

Description

@dp-sgr

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The OpenApi generator crashes on routes that starts with a '~' character.

e.g.

app.MapGet("/~health", () => Results.Ok("Works"));

While the endpoint "/~health" works as expected, the openapi endpoint crashes

Expected Behavior

The OpenApi impl should also be compatible with routes that start with ~ (like aspnetcore does).

The ~ may not be pretty from a design approach but the behavior of the OpenApi generator should match the behavior of aspnetcore.

Offtopic:
We are currently considering to migrate from /~endpoint to /.endpoint because we ship internally some default endpoints on every app

Steps To Reproduce

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.MapGet("/~health", () => Results.Ok("Works"));

app.MapOpenApi();

app.Run();

Exceptions (if any)

Microsoft.AspNetCore.Routing.Patterns.RoutePatternException: The route template cannot start with a '~' character unless followed by a '/'.
   at Microsoft.AspNetCore.Routing.Patterns.RoutePatternParser.TrimPrefix(String routePattern)
   at Microsoft.AspNetCore.Routing.Patterns.RoutePatternParser.Parse(String pattern)
   at ApiDescriptionExtensions.MapRelativePathToItemPath(ApiDescription apiDescription)
   at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.<>c.<GetOpenApiPathsAsync>b__20_1(ApiDescription apiDescription)
   at System.Linq.Lookup`2.Create(IEnumerable`1 source, Func`2 keySelector, IEqualityComparer`1 comparer)
   at System.Linq.Enumerable.GroupByIterator`2.MoveNext()
   at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiPathsAsync(OpenApiDocument document, IServiceProvider scopedServiceProvider, IOpenApiOperationTransformer[] operationTransformers, IOpenApiSchemaTransformer[] schemaTransformers, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.OpenApi.OpenApiDocumentService.GetOpenApiDocumentAsync(IServiceProvider scopedServiceProvider, HttpRequest httpRequest, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Builder.OpenApiEndpointRouteBuilderExtensions.<>c__DisplayClass0_0.<<MapOpenApi>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Http.Generated.<GeneratedRouteBuilderExtensions_g>F0399B8B15BE443123F4BECEE84B112C1912EE3F44D9DDD7BFA38E371FB917343__GeneratedRouteBuilderExtensionsCore.<>c__DisplayClass2_0.<<MapGet0>g__RequestHandler|5>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

10.0.100

Anything else?

This issue only appears if the route starts with ~

e.g.

app.MapGet("/x~health", () => Results.Ok("Works"));

would work

Metadata

Metadata

Assignees

Labels

area-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcfeature-openapi

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions