Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you enforce lowercase routing in ASP.NET Core?

For ASP.NET Core:

Add one of the following lines to the ConfigureServices method of the Startup class:

services.AddRouting(options => options.LowercaseUrls = true);

or

services.Configure<RouteOptions>(options => options.LowercaseUrls = true); 

Thanks to Skorunka for the answer as a comment. I thought it was worth promoting to an actual answer.


Update in ASP.NET Core Version >= 2.2

From ASP.NET Core 2.2, along with lowercase you can also make your route dashed using ConstraintMap which will make your route /Employee/EmployeeDetails/1 to /employee/employee-details/1 instead of /employee/employeedetails/1.

To do so, first create the SlugifyParameterTransformer class should be as follows:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        // Slugify value
        return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
    }
}

For ASP.NET Core 2.2 MVC:

In the ConfigureServices method of the Startup class:

services.AddRouting(option =>
{
    option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

And Route configuration should be as follows:

app.UseMvc(routes =>
{
     routes.MapRoute(
        name: "default",
        template: "{controller:slugify}/{action:slugify}/{id?}",
        defaults: new { controller = "Home", action = "Index" });
});

For ASP.NET Core 2.2 Web API:

In the ConfigureServices method of the Startup class:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => 
    {
        options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

For ASP.NET Core >=3.0 MVC:

In the ConfigureServices method of the Startup class:

services.AddRouting(option =>
{
    option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

And Route configuration should be as follows:

app.UseEndpoints(endpoints =>
{
      endpoints.MapAreaControllerRoute(
          name: "AdminAreaRoute",
          areaName: "Admin",
          pattern: "admin/{controller:slugify=Dashboard}/{action:slugify=Index}/{id:slugify?}");

      endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller:slugify}/{action:slugify}/{id:slugify?}",
          defaults: new { controller = "Home", action = "Index" });
});

For ASP.NET Core >=3.0 Web API:

In the ConfigureServices method of the Startup class:

services.AddControllers(options => 
{
    options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
});

For ASP.NET Core >=3.0 Razor Pages:

In the ConfigureServices method of the Startup class:

services.AddRazorPages(options => 
{
    options.Conventions.Add(new PageRouteTransformerConvention(new SlugifyParameterTransformer()));
})

This is will make /Employee/EmployeeDetails/1 route to /employee/employee-details/1


As other answers indicate, adding:

services.Configure<RouteOptions>(options => options.LowercaseUrls = true);

before

services.AddMvc(...)

works great, but I also want to add that if you use Identity, you will also need:

services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    var appCookie = options.Cookies.ApplicationCookie;
    appCookie.LoginPath = appCookie.LoginPath.ToString().ToLowerInvariant();
    appCookie.LogoutPath = appCookie.LogoutPath.ToString().ToLowerInvariant();
    appCookie.ReturnUrlParameter = appCookie.ReturnUrlParameter.ToString().ToLowerInvariant();
});

And obviously, replace both IdentityUser, and IdentityRole with your own classes if required.

I just tested this with .NET Core SDK 1.0.4 and the 1.0.5 runtime.


Found the solution.

In the assembly: Microsoft.AspNet.Routing, and the Microsoft.Extensions.DependencyInjection namespace, you can do this in your ConfigureServices(IServiceCollection services) method:

services.ConfigureRouting(setupAction =>
{
    setupAction.LowercaseUrls = true;
});

For identity, @Jorge Yanes Diez answer doesn't work in ASP.NET Core 2.2 (I think 2.x), so if you use Identity and ASP.NET Core 2.2 (2.x) here is the solution:

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = "/account/login";
    options.ReturnUrlParameter = "returnurl";
    ...
});

Ref: Configure ASP.NET Core Identity


It is worth noting that setting:

services.Configure<RouteOptions>(options => options.LowercaseUrls = true);

does not affect query strings.

To ensure that query strings are also lowercase, set the options.LowercaseQueryStrings to true:

services.Configure<RouteOptions>(options => 
{ 
    options.LowercaseUrls = true; 
    options.LowercaseQueryStrings = true;
});

However, setting this property to true is only relevant if options.LowercaseUrls is also true. options.LowercaseQueryStrings property is ignored if options.LowercaseUrls is false.