【问题标题】:Routed localization in ASP.NET Core 3.0 Razor PagesASP.NET Core 3.0 Razor 页面中的路由本地化
【发布时间】:2019-11-05 23:52:01
【问题描述】:

我想在我的 ASP.NET Core 3.0 Razor Pages 应用程序中使用路由本地化。

https://stackoverflow.com/a/52976625/107718 似乎有针对 2.2 的解决方案,但是在 3.0 中重新设计了路由/端点,有没有更好的方法来做到这一点?

【问题讨论】:

标签: c# asp.net-core asp.net-core-3.0


【解决方案1】:

ASP.NET Core 3.0 引入了 Endpoint Routing 的新功能,通过它我们可以在路由数据进入 MVC 之前从路由数据中获取文化。这使我们可以根据当前路线对内容进行本地化,而无需付出太多努力。

操作方法

首先,确保本地化服务已注册并且您已配置支持的文化,如下所示:

services.AddLocalization(opts =>  opts.ResourcesPath = "Resources" );
services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]{
        new CultureInfo("en-US"),
        new CultureInfo("de"),
        new CultureInfo("it"),
        // ... others
    };
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});

然后添加一个UseRequestLocalization中间件,并为文化配置一条路由,使其能够正确获取文化信息:

app.UseRouting(); app.UseRequestLocalization(); app.UseAuthorization(); app.UseEndpoints(端点 => { endpoints.MapControllerRoute(name: "culture-route", pattern:"{culture=en-US}/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute(名称:“默认”,模式:“{controller=Home}/{action=Index}/{id?}”); });

请注意,上述顺序很重要。

演示:


[编辑]

抱歉,我没有注意到您要求使用 Razor 页面。要使用 Razor Page WebApp,请创建自定义 IPageRouteModelConvention 以映射路线:

public class CustomCultureRouteRouteModelConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        List<SelectorModel> selectorModels = new List<SelectorModel>();
        foreach (var selector in model.Selectors.ToList())
        {
            var template = selector.AttributeRouteModel.Template;
            selectorModels.Add(new SelectorModel(){
                AttributeRouteModel = new AttributeRouteModel
                {
                    Template = "/{culture}" + "/" + template
                }
            });
        }
        foreach(var m in selectorModels){
            model.Selectors.Add(m);
        }
    }
}

并添加此页面约定:

services.AddRazorPages().AddRazorPagesOptions(opts =>
{
    opts.Conventions.Add(new CustomCultureRouteRouteModelConvention());
});
services.AddLocalization(opts => opts.ResourcesPath = "Resources");
services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[]{
        new CultureInfo("en-US"),
        new CultureInfo("de"),
        new CultureInfo("it"),
        new CultureInfo("zh"),
    };
    options.SupportedCultures = supportedCultures;
    options.SupportedUICultures = supportedCultures;
    options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
});

中间件:

app.UseRouting();

app.UseRequestLocalization();

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    //endpoints.MapControllerRoute(name: "culture-route", pattern:"{culture=en-US}/{controller=Home}/{action=Index}/{id?}");
    //endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});

【讨论】:

  • 这适用于 MVC,但我如何为 Razor 页面做到这一点?在UseEndpoints 里面我必须使用MapRazorPages 并且没有任何选项。
  • @Regent 抱歉,我没有注意到您要的是 Razor Pages。请参阅我的更新答案以了解如何执行此操作。
  • @itminus 当我尝试此代码时,它适用于任何字符串,例如/abc/Privacy。现在它不应该只适用于/{validCulture}/Privacy 的字符串。如何检查文化是否存在?
猜你喜欢
  • 2019-05-22
  • 2020-05-06
  • 2019-06-13
  • 2021-07-04
  • 2020-06-16
  • 2020-05-06
  • 2018-11-14
  • 1970-01-01
  • 2018-04-15
相关资源
最近更新 更多