Skip to content

Endpoint Routing does not respect AppendTrailingSlash property #64104

@64J0

Description

@64J0

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Hello, hope you're good.

After creating a Web API based on the official template and trying to set AppendTrailingSlash so that a trailing slash is not added to the route automatically, I noticed that this option does not work.

Expected Behavior

I want to define whether the routes are going to have the trailing slash appended automatically or not per route configuration.

If we can't do this for each route individually, I'd like to at least define this in the global scope.

Steps To Reproduce

  • Create a new project using the official template: dotnet new webapi -o SampleAppendTrailingSlash
  • Update the Program.cs:
using Microsoft.AspNetCore.Routing;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi().Configure<RouteOptions>(options =>
{
    // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    // The route options configuration
    options.AppendTrailingSlash = false;
    // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
});

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.MapOpenApi();
}

app.UseHttpsRedirection();

var summaries = new[]
{
    "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

// route without the trailing slash defined
app.MapGet("/weatherforecast", () =>
{
    var forecast = Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecast");

// route with the trailing slash defined
app.MapGet("/weatherforecast/", () =>
{
    var forecast =  Enumerable.Range(1, 5).Select(index =>
        new WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(-20, 55),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    return forecast;
})
.WithName("GetWeatherForecastTrailingSlash");

app.Run();

record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
{
    public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

Exceptions (if any)

fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches:

  HTTP: GET /weatherforecast
  HTTP: GET /weatherforecast/
     at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(Span`1 candidateState)
     at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ProcessFinalCandidates(HttpContext httpContext, Span`1 candidateState)
     at Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.Select(HttpContext httpContext, Span`1 candidateState)
     at Microsoft.AspNetCore.Routing.Matching.DfaMatcher.MatchAsync(HttpContext httpContext)
     at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
     at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

.NET Version

SDK 9.0.302

Anything else?

Related to giraffe-fsharp/Giraffe#680

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