您如何在 ASP.NET Core 中实施小写路由?

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

在 ASP.NET 4 中,这与在应用程序的 RegisterRoutes 处理程序中 routes.LowercaseUrls = true; 一样简单。

我无法在 ASP.NET Core 中找到实现此目的的等效项。我认为它会在这里:

app.UseMvc(configureRoutes =>
{
    configureRoutes.MapRoute("Default", "{controller=App}/{action=Index}/{id?}");
});

但是 configureRoutes 中没有任何内容看起来允许它......除非有一个我在文档中找不到的扩展方法?

找到解决方案。

在程序集:Microsoft.AspNet.RoutingMicrosoft.Extensions.DependencyInjection 命名空间中,您可以在 ConfigureServices(IServiceCollection services) 方法中执行此操作:

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

对于ASP.NET核心:

将以下行之一添加到 Startup class 的 ConfigureServices 方法中:

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

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

感谢 Skorunka 的回答作为评论。我认为值得推广为实际答案。

如其他答案所示,添加:

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

之前

services.AddMvc(...)

效果很好,但我还想补充一点,如果您使用 Identity,您还需要:

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();
});

显然,如果需要,请将 IdentityUserIdentityRole 替换为您自己的 类。

我刚刚使用 .NET Core SDK 1.0.4 和 1.0.5 运行时对此进行了测试。

在 ASP.NET 核心版本中更新 >= 2.2

ASP.NET Core 2.2,连同小写字母[=7​​5=]你也可以让你的路线虚线 使用 ConstraintMap 这将使你的路线 /Employee/EmployeeDetails/1/employee/employee-details/1 而不是 /employee/employeedetails/1.

为此,首先创建SlugifyParameterTransformer class 应该如下:

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

对于 ASP.NET 核心 2.2 MVC:

StartupConfigureServices方法中 class:

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

Route配置如下:

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

对于 ASP.NET Core 2.2 Web API:

StartupConfigureServices方法中 class:

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

对于 ASP.NET Core >=3.0 MVC:

StartupConfigureServices方法中 class:

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

Route配置如下:

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" });
});

对于 ASP.NET Core >=3.0 Web API:

StartupConfigureServices方法中 class:

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

对于 ASP.NET Core >=3.0 Razor Pages:

StartupConfigureServices方法中 class:

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

这将使 /Employee/EmployeeDetails/1 路由到 /employee/employee-details/1

对于身份, 答案在 ASP.NET Core 2.2 中不起作用(我认为 2.x),所以如果您使用身份和ASP.NET Core 2.2 (2.x) 解决方法如下:

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

参考:Configure ASP.NET Core Identity

我在 RegisterRoutes::RouteConfig 上有这个:

routes.LowercaseUrls = 真;

值得注意的是设置:

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

不影响查询字符串

要确保查询字符串也是小写,请将 options.LowercaseQueryStrings 设置为 true:

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

但是,将此 属性 设置为 true 仅在 options.LowercaseUrls 也为 true 时才有意义。如果 options.LowercaseUrlsfalseoptions.LowercaseQueryStrings 属性 将被忽略。