【问题标题】:How do you enforce lowercase routing in ASP.NET Core?如何在 ASP.NET Core 中强制执行小写路由?
【发布时间】:2016-07-21 09:40:38
【问题描述】:

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

我在 ASP.NET Core 中找不到实现此目的的等效项。我想它会在这里:

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

但是configureRoutes 中的任何内容似乎都不允许...除非在某个地方有我在文档中找不到的扩展方法?

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc asp.net-core-routing


    【解决方案1】:

    对于 ASP.NET Core:

    Startup 类的ConfigureServices 方法中添加以下行之一:

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

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

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

    【讨论】:

    • 值得注意的是,您应该在实际调用 AddMvc() 之前将其放入您的 Startup.ConfigureServices() 方法中。 AddRouting() 也被 AddMvc() 调用,它使用了方法的 Try 变体,用于将依赖项添加到服务集合。因此,当它看到已经添加了路由依赖项时,它将跳过AddMvc() 设置逻辑的那部分。
    • 切换到正确答案,因为我的是在 asp 4 到核心的过渡期间。
    • @NickAlbrecht 如果在之前或之后调用它似乎没有什么区别(至少从 ASP.NET Core 5.0 开始)。 AddRouting() 无论如何都会被调用两次,所以顺序无关紧要。
    • 我相信这是围绕 .NET Core 3.x 完成的。他们改变了它,使路由成为一个独立的功能,而不是与 MVC 捆绑在一起。我不相信路由是从AddMvc(或者AddControllersWithViews,如果你不需要RazorPages)调用的。因此,仅当您使用 AspNetCore 2 时,顺序才真正重要。(不记得这是否是 1.x 中的选项)。但是他们确实将小写行为分为两个设置,因此如果您想要完全小写的地址,您需要将LowercaseUrlsLowercaseQueryStrings 都设置为true
    • 你能澄清一下,第二个选项是针对 Razor Pages 而第一个是针对 MVC 吗?
    【解决方案2】:

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

    ASP.NET Core 2.2 开始,除了 lowercase,您还可以使用 ConstraintMap 使您的 路由虚线,这将使您的路由/Employee/EmployeeDetails/1/employee/employee-details/1 而不是 /employee/employeedetails/1

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

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

    对于 ASP.NET Core 2.2 MVC:

    Startup 类的ConfigureServices 方法中:

    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:

    Startup类的ConfigureServices方法中:

    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:

    Startup类的ConfigureServices方法中:

    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:

    Startup 类的ConfigureServices 方法中:

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

    对于 ASP.NET Core >=3.0 Razor 页面:

    Startup类的ConfigureServices方法中:

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

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

    【讨论】:

    • 我也试过这段代码和微软官方代码,但是“slugify”参数转换器没有效果。它只是被路由系统忽略(因此 URL 不会被替换为虚线)。为了检查自己,我将记录器放入 TransformOutbound() 方法中,但没有从那里调用。
    • 好的!请让我检查一下!
    • @user3172616 我已经检查过了!它按预期工作!比如生成路由为employee-details。请给我看看你的配置好吗?
    • @user3172616 你在测试的路由上使用属性路由吗?
    • 我在 Visual Studio 的全新核心 v2.2 解决方案上使用标准路由方法(不是属性路由)。有两个屏幕截图(c# 代码和 .cshtml 代码)。我试图以不同的方式生成链接,但没有任何效果。 imgur.com/a/L8dCF6c
    【解决方案3】:

    正如其他答案所示,添加:

    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 运行时对此进行了测试。

    【讨论】:

    • Configure() 是最好的答案恕我直言:小巧而直接(在 mvc core 3.1 上测试)
    【解决方案4】:

    找到了解决办法。

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

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

    【讨论】:

    • 对于 ASP NET MVC CORE:services.AddRouting(options => { options.LowercaseUrls = true; });
    • Microsoft.AspNetCore.Routing.dll 中的 Microsoft.Extensions.DependencyInjection
    • 在 RTM 之前是这样,现在你应该使用 .AddRouting 代替 .ConfigureRouting
    【解决方案5】:

    值得注意的是设置:

    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.LowercaseUrlsfalse,则options.LowercaseQueryStrings 属性将被忽略。

    【讨论】:

      【解决方案6】:

      对于身份,@Jorge Yanes Diez 答案在ASP.NET Core 2.2 中不起作用(我认为是 2.x),所以如果你在这里使用 Identity 和 ASP.NET Core 2.2 (2.x)是解决方案:

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

      参考:Configure ASP.NET Core Identity

      【讨论】:

        【解决方案7】:

        我在 RegisterRoutes::RouteConfig: 上有这个:

        routes.LowercaseUrls = true;

        【讨论】:

        • 适用于 asp.net mvc 5
        猜你喜欢
        • 1970-01-01
        • 2012-10-12
        • 2018-03-17
        • 1970-01-01
        • 2017-03-13
        • 1970-01-01
        • 1970-01-01
        • 2010-10-27
        • 2020-11-02
        相关资源
        最近更新 更多