Search code examples
asp.net-core-webapi.net-7.0asp.net-web-api-routing

How do I set a prefix in my ASP.NET Core 7 Web API for all endpoints?


I am retrieving a string from my appsettings.json:

{
  "ConnectionStrings": {
    //several strings
  },
  "BaseRoute": {
    "Base": "/myapi/"
  }
}

And I have class:

public class BaseRoute
{
    public string Base { get; set; }
}

In my Program.cs I have configured:

var builder = WebApplication.CreateBuilder(args);
// ...
builder.Services.Configure<BaseRoute>(builder.Configuration.GetSection("BaseRoute"));
var baseroute = builder.Configuration.GetSection("BaseRoute").Get<BaseRoute>();
builder.Services.AddSingleton(resolver => resolver.GetRequiredService<IOptions<BaseRoute>>().Value);
// ...
var app = builder.Build();

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

app.UseMiddleware<JwtRefresher>();
app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.UsePathBase(new PathString(baseroute.Base));
app.UseRouting();
app.Run();

But no prefix is set in my Swagger endpoints when I run the api. How should I solve this?

I even tried placing the app.UsePathBase(new PathString("/api")); higher up:

var app = builder.Build();
app.UsePathBase(new PathString(baseroute.Base));
app.UseRouting();

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

app.UseMiddleware<JwtRefresher>();
app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

Or replaced the variable in the PathString argument with a fixed string:

var app = builder.Build();
app.UsePathBase(new PathString("/api"));
app.UseRouting();

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

app.UseMiddleware<JwtRefresher>();
app.UseHttpsRedirection();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

But I still won't get the desired result.

What am I doing wrong?


Solution

  • Configre swagger like below:

    app.UsePathBase(new PathString("/api"));
    app.UseRouting();
    // Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {
        var basePath = "/api";
        app.UseSwagger(c =>
        {
            c.RouteTemplate = "swagger/{documentName}/swagger.json";
            c.PreSerializeFilters.Add((swaggerDoc, httpReq) =>
            {
                swaggerDoc.Servers = new List<OpenApiServer> { new OpenApiServer { Url = $"{httpReq.Scheme}://{httpReq.Host.Value}{basePath}" } };
            });
        });
        app.UseSwaggerUI();
    }
    

    Test
    enter image description here

    A workaround to change base path:
    Delete app.UsePathBase(You could also delete app.UseRouting when you don't use usepathbase), Replace app.MapControllers with following

    app.MapControllerRoute(
        name: "default",
        pattern:"api/{controller}/{action}/{id?}"
        );
    

    (Just note that {id?} is just a pattern, you could use it for any parameter other than "id");
    In this way, you needn't to change swagger prefix.
    enter image description here