Home > Blockchain >  How can I define a .NET 6 Minimal Web API route that includes a colon?
How can I define a .NET 6 Minimal Web API route that includes a colon?

Time:11-05

I've created a .NET 6 Minimal Web API that needs to support a particularly formatted URL. The URL that needs to be accepted is similar to /sensor/sensor:123/measurement

The following is the relevant Program.cs.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.MapGet("/sensor/sensor:{sensorId}/measurement", (int sensorId) =>
{
    return Results.Ok();
});

app.Run();

However, when I run this and check the generated Swagger UI I see the GET URL listed as /sensor/sensor}/measurement. Trying it out properly shows the sensorId as a path parameter, but actually entering data and executing via this interface results in a 404.

If I modify it to the following, I can get it to run, and it allows me to pass the colon in the request, but I would prefer if the colon was part of the route definition, since it a) should be and b) requires extra parsing logic.

app.MapGet("/sensor/sensor{sensorId}/measurement", (string sensorId) =>
{
    return Results.Ok();
});

Is there a way to allow/escape colons in .NET 6 Minimal Web APIs so they can be part of the defined route?

CodePudding user response:

In ASP.NET Core, : is a special character in the route if between {}. But a bug in Swashbuckle that interpret : outside {} like it's inside.

https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2310

That is fixed in the version 6.2.4. But actually, the ASP.NET Core API template add Swashbuckle at version 6.2.3 with the bug.

We need to update manually the NuGet package Swashbuckle.

CodePudding user response:

TL;DR

Update Swashbuckle to the latest 6.4.0 version.

More info:

Colon is a special symbol in ASP.NET Core route templates and is used to constraint route segments/values:

The GetIntProduct action contains the int/{id:int} template. The :int portion of the template constrains the id route values to strings that can be converted to an integer.

[HttpGet("int/{id:int}")] // GET /api/test2/int/3
public IActionResult GetIntProduct(int id)
{
    return ControllerContext.MyDisplayRouteInfo(id);
}

It seems that you are using Swashbuckle which is considering this colon as part of constraint cause actually invoking endpoint directly via %server-uri%/sensor/sensor:123/measurement works.

UPD

Update Swashbuckle to latest 6.4.0, it has the issue fixed (the fixed version, the one which was not working for me - 6.2.3 which is included in the template)

  • Related