ASP.NET MVC Core中身份验证页面的路由本地化

6
我目前正在开发一个ASP.NET MVC Core的Web应用程序,用户需要注册。这是一个本地化的Web应用程序,应该能够运行多种语言。为了友好的SEO,我选择了路由本地化,所以我的URL看起来像这样:https://localhost:5001/en/Cataloguehttps://localhost:5001/fr/catalogue
为了实现这一点,在Startup.cs中的ConfigureServices方法中添加了以下代码:
services.AddLocalization(options => options.ResourcesPath = "Resources");

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
            .AddViewLocalization()
            .AddDataAnnotationsLocalization();

在我的Configure方法中,我添加了以下内容:
IList<CultureInfo> supportedCultures = new List<CultureInfo>
{
    new CultureInfo("en"),
    new CultureInfo("fr"),
};
var localizationOptions = new RequestLocalizationOptions
{
    DefaultRequestCulture = new RequestCulture("en"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
};
var requestProvider = new RouteDataRequestCultureProvider();
localizationOptions.RequestCultureProviders.Insert(0, requestProvider);

app.UseRouter(routes =>
{
    routes.MapMiddlewareRoute("{culture=en}/{*mvcRoute}", subApp =>
    {
        subApp.UseRequestLocalization(localizationOptions);

        subApp.UseMvc(mvcRoutes =>
        {
            mvcRoutes.MapRoute(
                name: "areaRoute",
                template: "{culture=en}/{area:exists}/{controller=Home}/{action=Index}/{id?}");

            mvcRoutes.MapRoute(
                name: "default",
                template: "{culture=en}/{controller=Home}/{action=Index}/{id?}");
        });
    });
});

这个方法非常有效。我可以将我的MVC页面翻译成任何语言。但是我的问题在于身份验证页面。我将这些页面添加为脚手架项。它们的URL指向https://localhost:5001/Identity/Account/Register。尝试使用https://localhost:44339/en/Identity/Account/Register访问它们无法正常工作。我该如何实现身份验证页面的路由本地化?

这可能是一个愚蠢的问题,但你不能使用属性路由来手动设置一些有问题的页面路由吗?https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/ - Iskandar Reza
嗨,Iskander,我可以为我的视图做到这一点 - 正如您可以从我附加到原始问题的代码中看到的那样 - 但我无法为身份Razor页面做到这一点。无论如何,我不喜欢Microsoft在这些身份脚手架项目中使用Razor页面的事实。 - Roel Geusens
1个回答

10

AddAreaFolderRouteModelConvention会起到魔法般的作用:

services.AddMvc()
    .AddRazorPagesOptions(options =>
    {
        options.Conventions.AddAreaFolderRouteModelConvention("Identity", "/Account/", model =>
         {
             model.Selectors.ForEach(x =>
             {
                 if (x.AttributeRouteModel.Template.StartsWith("Identity"))
                 {
                     x.AttributeRouteModel = new AttributeRouteModel()
                     {
                         Order = -1,
                         Template = AttributeRouteModel.CombineTemplates(("{culture=en-US}"),
                             x.AttributeRouteModel.Template)
                     };
                 }
             });


         });
    });

MSDN页面说:

pageName 字符串 页面名称,例如 /Users/List

页面名称是文件的路径,不包括扩展名,相对于指定区域的页面根目录。例如,文件 Areas/Identity/Pages/Manage/Accounts.cshtml 的页面名称为 /Manage/Accounts。

因此,所有页面实际上都在 "/Account/" 内,以下是一些生成的链接:

/en-us/identity/account/login
/en-us/identity/account/manage/index
/en-us/identity/account/manage/orders

如果您不喜欢路径中包含"/identity/",可以这样做:
AttributeRouteModel.CombineTemplates(("{culture=en-US}"), 
  x.AttributeRouteModel.Template.Substring("Identity/".Length)) //<==Substring

然后所有的链接将是:
/en-us/account/login
/en-us/account/manage/index
/en-us/account/manage/orders

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接