我试图在asp核心项目中添加多语言功能,但是 3.1和5.0在RequestLocalization中有一些更改,但我无法获得想要的东西.我为每种语言添加了资源文件,并在剃须刀页面中使用了资源,它可以正常工作,但是有一个不需要的默认路由错误,我希望我的路由对默认区域性友好.
这就是我想要的,
对于默认区域性(土耳其语):
site/foosite/foo/barsite/foo/bar/5对于非默认区域性(英语):
site/en/foosite/zh-CN/foo/barsite/zh-CN/foo/bar/5我的另一个问题是;我的项目将site/foo/foo/bar这样的网址呈现为site/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天.您可能要针对生产方案更改此设置,请参见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-core project but there are some changes between 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/foo site/foo/bar site/foo/bar/5For non-default culture (English):
site/en/foo site/en/foo/bar site/en/foo/bar/5My other problem is; My project renders site/foo/foo/bar this url like site/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 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?
EDITI 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:
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); } }
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 }); });
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?}"); });
Views.Home.Index.en-US.resx Views.Home.Index.fr-FR.resx
@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中的默认区域性
发布评论