ASP.NET Core 5.0 RouteDataRequestCultureProvider删除URL中的默认区域性 [英] ASP.NET Core 5.0 RouteDataRequestCultureProvider remove default culture in url

查看:50
本文介绍了ASP.NET Core 5.0 RouteDataRequestCultureProvider删除URL中的默认区域性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在asp.net核心项目中添加多语言功能,但是.net 3.1和5.0在RequestLocalization中有一些更改,但我无法获得想要的东西.我为每种语言添加了资源文件,并在剃须刀页面中使用了资源,它可以正常工作,但是有一个不需要的默认路由错误,我希望我的路由对默认区域性友好.

这就是我想要的,

对于默认区域性(土耳其语):

  site.com/foosite.com/foo/barsite.com/foo/bar/5 

对于非默认区域性(英语):

  site.com/en/foosite.com/zh-CN/foo/barsite.com/zh-CN/foo/bar/5 

我的另一个问题是;我的项目将site.com/foo/foo/bar这样的网址呈现为site.com/tr/foo/bar,这不好,我想应该将其重定向到404页面.

我的启动示例代码如下:

  public void ConfigureServices(IServiceCollection服务){services.AddResponseCompression();services.AddLocalization(opts => opts.ResourcesPath ="Resources");services.Configure< RequestLocalizationOptions>(options =>{varsupportedCultures = new []{新的CultureInfo("tr-TR"),新的CultureInfo("en")};options.DefaultRequestCulture = new RequestCulture("tr");options.SupportedCultures = supportCultures;options.SupportedUICultures = supportCultures;options.RequestCultureProviders.Insert(0,新的RouteDataRequestCultureProvider());});services.AddControllersWithViews();services.AddRazorPages();services.AddRouting(options => options.LowercaseUrls = true);}公共无效配置(IApplicationBuilder应用程序,IWebHostEnvironment env){app.UseResponseCompression();如果(env.IsDevelopment())app.UseDeveloperExceptionPage();别的{app.UseExceptionHandler("/Home/Error");//HSTS的默认值为30天.您可能要针对生产方案更改此设置,请参见https://aka.ms/aspnetcore-hsts.app.UseHsts();}app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();varsupportedCultures = new string [] {"tr-TR","en"};app.UseRequestLocalization(options =>选项.AddSupportedCultures(支持的文化).AddSupportedUICultures(supportedCultures).SetDefaultCulture("tr-TR").RequestCultureProviders.Insert(0,新的CustomRequestCultureProvider(上下文=> Task.FromResult(新的ProviderCultureResult("tr-TR"))))));app.UseAuthorization();app.UseEndpoints(endpoints =>{Endpoints.MapControllerRoute(名称:"culture-route",模式:"{culture}/{controller = Home}/{action = Index}/{id?}");endpoints.MapControllerRoute(name:"default","{culture = tr}/{controller = Home}/{action = Index}/{id?}");});} 

剃刀资源的使用和文化变革的导航

资源文件

我该如何解决?我在做什么错了?

编辑

我发现了

英语->

法语->

您可以问我问题,并享受本地化的乐趣:)

I tried to add multi language feature to my asp.net-core project but there are some changes between .net 3.1 and 5.0 in RequestLocalization and i couldn't get what i want. I added Resource files for each language and I used Resource in my razor pages, its working but there is one unwanted default route bug and i want my routing to work friendly for default culture.

This is what i want,

For default culture (Turkish):

site.com/foo
site.com/foo/bar
site.com/foo/bar/5

For non-default culture (English):

site.com/en/foo
site.com/en/foo/bar
site.com/en/foo/bar/5

My other problem is; My project renders site.com/foo/foo/bar this url like site.com/tr/foo/bar it's not okay and i guess it should redirect to 404 page.

My Startup sample code below:

public void ConfigureServices(IServiceCollection services)
{
    services.AddResponseCompression();
    services.AddLocalization(opts => opts.ResourcesPath = "Resources");
    services.Configure<RequestLocalizationOptions>(options =>
    {
        var supportedCultures = new[]
        {
            new CultureInfo("tr-TR"),
            new CultureInfo("en")
        };

        options.DefaultRequestCulture = new RequestCulture("tr");
        options.SupportedCultures = supportedCultures;
        options.SupportedUICultures = supportedCultures;
        options.RequestCultureProviders.Insert(0, new RouteDataRequestCultureProvider());
    });

    services.AddControllersWithViews();
    services.AddRazorPages();
    services.AddRouting(options => options.LowercaseUrls = true);
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseResponseCompression();

    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();
    else
    {
        app.UseExceptionHandler("/Home/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    var supportedCultures = new string[] { "tr-TR", "en" };
    app.UseRequestLocalization(options =>
                options
                .AddSupportedCultures(supportedCultures)
                .AddSupportedUICultures(supportedCultures)
                .SetDefaultCulture("tr-TR")
                .RequestCultureProviders.Insert(0, new CustomRequestCultureProvider(context => Task.FromResult(new ProviderCultureResult("tr-TR"))))
    );

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

Razor Resource usage and culture change navs

Resource files

How can I solve this or what am I doing wrong?

EDIT

I found this approach. It's using CookieRequestCultureProvider and there is no culture info in url but at least there are no corupted urls. I don't know if this is okay for SEO.

解决方案

You need to configure localization in ASP.Net Core a little bit different for this purpose.

I have created new ASP.Net Core MVC project and do the following steps:

  1. First of all, you need to create custom UrlRequestCultureProvider

    public class UrlRequestCultureProvider : RequestCultureProvider
    {
        private static readonly Regex PartLocalePattern = new Regex(@"^[a-z]{2}(-[a-z]{2,4})?$", RegexOptions.IgnoreCase);
        private static readonly Regex FullLocalePattern = new Regex(@"^[a-z]{2}-[A-Z]{2}$", RegexOptions.IgnoreCase);

        private static readonly Dictionary<string, string> LanguageMap = new Dictionary<string, string>
        {
            { "en", "en-US" },
            { "fr", "fr-FR" }
        };

        public override Task<ProviderCultureResult> DetermineProviderCultureResult(HttpContext httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException(nameof(httpContext));
            }

            var parts = httpContext.Request.Path.Value.Split('/');
            // Get culture from path
            var culture = parts[1];

            if (parts.Length < 3)
            {
                return Task.FromResult<ProviderCultureResult>(null);
            }

            // For full languages fr-FR or en-US pattern
            if (FullLocalePattern.IsMatch(culture))
            {
                return Task.FromResult(new ProviderCultureResult(culture));
            }

            // For part languages fr or en pattern
            if (PartLocalePattern.IsMatch(culture))
            {
                var fullCulture = LanguageMap[culture];
                return Task.FromResult(new ProviderCultureResult(fullCulture));
            }

            return Task.FromResult<ProviderCultureResult>(null);
        }
    }

  1. In ConfigureServices() add this code:

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

            services.Configure<RequestLocalizationOptions>(options =>
            {
                var supportedCulters = new List<CultureInfo>()
                {
                    new CultureInfo("en-US"),
                    new CultureInfo("fr-FR")
                };

                options.DefaultRequestCulture = new RequestCulture(supportedCulters.FirstOrDefault());
                options.SupportedCultures = supportedCulters;
                options.SupportedUICultures = supportedCulters;

                options.RequestCultureProviders.Insert(0, new UrlRequestCultureProvider() 
                { 
                    Options = options 
                });
            });

  1. In Configure() add this code:

            var requestLocalizationOptions = app.ApplicationServices.GetRequiredService<IOptions<RequestLocalizationOptions>>();
            app.UseRequestLocalization(requestLocalizationOptions.Value);

            app.UseRouting();

            app.UseAuthorization();

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

                endpoints.MapControllerRoute(
                    name: "culture",
                    pattern: "{culture}/{controller=Home}/{action=Index}/{id?}");
            });

  1. Also, I added Resources for en-US and fr-FR localization. More information about Resource file naming in Microsoft documentation.

Views.Home.Index.en-US.resx
Views.Home.Index.fr-FR.resx

  1. Finally, this is my Home view

@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer

@{
    ViewData["Title"] = "Home Page";
}

<div class="text-center">
    <h1 class="display-4">@Localizer["Welcome"]</h1>
</div>

The results you can see on the screenshots.

Defaul ->

English ->

French ->

You can ask me questions and have fun with localizations :)

这篇关于ASP.NET Core 5.0 RouteDataRequestCultureProvider删除URL中的默认区域性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆