ASP.Net Core 2.2 Upgrade - Default Route Redirection Issue
Asked Answered
C

2

6

Until Asp.Net Core 2.1, I was using below code in order to redirect default route to swagger endpoint.

app.UseMvc(builder =>
{
    builder.MapRoute("default", template: "api/{controller}/{action}/{id?}");
    builder.MapGet("", context =>
    {
        context.Response.Redirect("./swagger/index.html", permanent: false);
        return Task.FromResult(0);
    });

});

However, when I upgraded to Asp.Net Core 2.2 this code did not work as expected (redirection is called)

Is this known issue? How can I solve it?

Edit: Thanks to @KirkLarkin

I have changed options.EnableEndpointRouting to false and now it is working. However as I unsderstand this is legacy routing method.

What do I need to do in order to make routing with options.EnableEndpointRouting = true;?

Celik answered 17/1, 2019 at 14:24 Comment(2)
I expect this is something that's changed re MVC switching to Endpoint Routing. You shouldn't need to try and handle this route via MVC - you can just clear RoutePrefix in the call to UseSwaggerUI(...). i.e. app.UseSwaggerUI(o => o.RoutePrefix = string.Empty);.Slipsheet
It has been long time that I am not using UseSwaggerUI since SwaggerUI updates were not frequent. Also, I have custom implementations in my swagger.js. Hence, I need custom routing :)Incongruous
S
13

Given that the redirect you are applying here does not relate directly to ASP.NET Core MVC, one option is to Use Routing Middleware instead of adding the route within MVC itself. Here's an example:

app.UseRouter(builder =>
{
    builder.MapGet("", context =>
    {
        context.Response.Redirect("./swagger/index.html", permanent: false);
        return Task.FromResult(0);
    });
});

The parameter passed into the UseRouter delegate (builder) is an instance of RouteBuilder, which is the same type that is passed into the UseMvc delegate. In the example above, we just apply the required route directly.

This call can be added either before or after your existing call to UseMvc, but adding it before might be more logical (and maybe slightly more performant) seeing as the decision to redirect can be made without involving MVC.

It's worth noting that this approach doesn't use endpoint routing at all. In ASP.NET Core 2.2, Endpoint Routing only applies to ASP.NET Core MVC:

With the release of endpoint routing in ASP.NET Core 2.2, endpoint linking is limited to MVC/Razor Pages actions and pages. The expansions of endpoint-linking capabilities is planned for future releases.

Perhaps in the near future, this routing middleware approach will also change, but for now the approach I've provided works well and is fully supported.

As an alternative to using the routing middleware, it's also possible to use a simple custom middleware function to do the redirect. Here's an example of that for completeness:

app.Use(async (context, next) =>
{
    if (context.Request.Path == "/")
    {
        context.Response.Redirect("./swagger/index.html", permanent: false);
        return;
    }

    await next();
});

There are even more options for achieving this, but I won't enumerate them all here.

Slipsheet answered 18/1, 2019 at 10:40 Comment(0)
D
1

It should be worth noting that in ASP.NET Core 3.1, the following works:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/", context =>
    {
        context.Response.Redirect("swagger/index.html", permanent: false);
        return Task.CompletedTask;
    });

    endpoints.MapControllers();
});
Delude answered 26/1, 2021 at 13:1 Comment(1)
I actually had to use this: endpoints.MapGet("/index.html", context => ...Marsha

© 2022 - 2024 — McMap. All rights reserved.