ChatGPT解决这个技术问题 Extra ChatGPT

如何在 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 中没有任何内容看起来允许它......除非在某个地方有一个我在文档中找不到的扩展方法?


D
Dmitrii Tarasov

对于 ASP.NET 核心:

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

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

或者

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

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


值得注意的是,您应该在 Startup.ConfigureServices() 方法中实际调用 AddMvc() 之前将其放入。 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?
T
TanvirArjel

更新 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
J
Jorge Yanes Diez

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

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 上测试)
m
mariocatch

找到了解决方案。

在程序集: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
A
Amal K

值得注意的是,设置:

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

不影响查询字符串。

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

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

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


M
Mehdi Dehghani

对于身份,@Jorge Yanes Diez 答案在 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


p
paburgos

我在 RegisterRoutes::RouteConfig 上有这个:

routes.LowercaseUrls = true;


它适用于 asp.net mvc 5