首页 > 解决方案 > Asp.NET Core 3.1 RazorPages 本地化 SEO 友好的 URL

问题描述

我对上述问题进行了大量研究,但找不到解决问题的正确解决方案。让我解释一下,我正在使用 RazorPages 和 .Net Core 3.1 编写一个应用程序,它是多语言的,我希望它的行为类似于大多数使用 SEO 友好 URL 和本地化的网站,例如:

https://www.microsoft.com/en-us/windows/
https://www.microsoft.com/it-it/windows/

这样我在 URI 路径中有一个文化参数,并使用它以正确的语言显示我的页面。

我试图在启动中添加这个:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new[]
        {
            new CultureInfo("en"),
            new CultureInfo("de"),
            new CultureInfo("fr"),
            new CultureInfo("es"),
            new CultureInfo("ru"),
            new CultureInfo("ja"),
            new CultureInfo("ar"),
            new CultureInfo("zh"),
            new CultureInfo("en-GB")
        };
        options.DefaultRequestCulture = new RequestCulture("en-GB");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
        options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider(){ Options = options});
    });


    services.AddLocalization(options => options.ResourcesPath = "Resources");

    services.AddRazorPages(options =>
    {
        options.Conventions.Add(new CultureTemplatePageRouteModelConvention());
    })
    .AddViewLocalization();
}

其中 CultureTemplatePageRouteModelConvention 是:

public class CultureTemplatePageRouteModelConvention : IPageRouteModelConvention
{
    public void Apply(PageRouteModel model)
    {
        var selectorCount = model.Selectors.Count;

        for (var i = 0; i < selectorCount; i++)
        {
            var selector = model.Selectors[i];

            model.Selectors.Add(new SelectorModel
            {
                AttributeRouteModel = new AttributeRouteModel
                {
                    Order = -1,
                    Template = AttributeRouteModel.CombineTemplates("{culture?}",
                        selector.AttributeRouteModel.Template),
                }
            });
        }
    }
}

然后添加中间件:

.....
app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();
var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(localizationOptions);

app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
});

但似乎没有任何效果。你有解决这个问题的办法吗?如果没有,我怎样才能实现我的目标?谢谢

标签: c#asp.net-corelocalizationrazor-pages

解决方案


这就是我在我的项目中所做的,它对我有用。在 Startup.cs 文件的 ConfigureServices 中添加以下代码:

services.AddRazorPages().AddRazorPagesOptions(options =>
{
    //options.Conventions.AuthorizeFolder("/Account/Manage");
    //options.Conventions.AuthorizePage("/Account/Logout");
    options.Conventions.AddFolderRouteModelConvention("/", model =>
    {
        foreach (var selector in model.Selectors)
        {
            var attributeRouteModel = selector.AttributeRouteModel;
            attributeRouteModel.Template = AttributeRouteModel.CombineTemplates("{lang=en-US}", attributeRouteModel.Template);
        }
    });
});

IList<CultureInfo> supportedCultures = new List<CultureInfo>
{
    new CultureInfo("en-US"),
    new CultureInfo("el-GR"),
};

var MyOptions = new RequestLocalizationOptions()
{
    DefaultRequestCulture = new RequestCulture(culture: "en-US", uiCulture: "en-US"),
    SupportedCultures = supportedCultures,
    SupportedUICultures = supportedCultures
};
MyOptions.RequestCultureProviders = new[]
{
        new RouteDataRequestCultureProvider() { RouteDataStringKey = "lang", Options = MyOptions }
};

services.AddSingleton(MyOptions);

生成以下类:

public class LocalizationPipeline
{
    public void Configure(IApplicationBuilder app, RequestLocalizationOptions options)
    {
        app.UseRequestLocalization(options);
    }
}

现在在你的 razor pages 类上添加以下属性:

[MiddlewareFilter(typeof(LocalizationPipeline))]
public class ExampleModel : PageModel
{

推荐阅读