Add the NuGet package DesignLocal.JsonLocalizer to any ASP.NET Core project supporting ASP.NET Core 3.0 or higher.
Add localization configuration to your startup.cs file. The important steps here are to add ConfigureLocalizationServices(), .AddViewLocalization() and .AddDataAnnotationsLocalization() to ConfigureServices(), then add app.UseRequestLocalization() to Configure() and configure endpoits to support RoteDataRequestProvider
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Localization.Routing;
using x6.JsonLocalizer;
using x6.JsonLocalizer.Extensions;
public void ConfigureServices(IServiceCollection services)
{
//Localization services initialization
ConfigureLocalizationServices(services);
services.AddControllersWithViews()
.AddDataAnnotationsLocalization()
.AddViewLocalization()
.AddRazorRuntimeCompilation();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseRequestLocalization(); //this line should be after app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
//endpoints.MapControllerRoute(name: "culture-route", pattern: "{culture=en}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(name: "culture-route", pattern: "{culture?}/{controller=Home}/{action=Index}/{id?}");
endpoints.MapControllerRoute(name: "default", pattern: "{controller=Home}/{action=Index}/{id?}");
});
}
private void ConfigureLocalizationServices(IServiceCollection services)
{
CultureInfo defaultCulture = CultureInfo.GetCultureInfo("en");
List<CultureInfo>supportedCultures = Configuration.GetSection("Localizaion:SupportedCultures").Get<List<CultureInfo>>();
string cookieName = Configuration.GetValue<string>("Localizaion:CookieName")??"uiculture";
bool fallbackToParentCulture = Configuration.GetValue<bool>("Localizaion:FallbackToParentCulture");
string queryStringKey = Configuration.GetValue<string>("Localizaion:QueryStringKey")??"culture";
string uiQueryStringKey = Configuration.GetValue<string>("Localizaion:UIQueryStringKey") ?? "ui-culture";
if (supportedCultures.Count == 0)
{
supportedCultures.Add(defaultCulture);
}
else
{
defaultCulture = supportedCultures[0];
}
services.Configure<RequestLocalizationOptions>(options =>
{
options.DefaultRequestCulture = new RequestCulture(defaultCulture.Name);
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.FallBackToParentCultures = fallbackToParentCulture;
options.FallBackToParentUICultures = fallbackToParentCulture;
options.RequestCultureProviders.Clear();
/*
Priority of provides matters here. Culture fallback stack:
1. Cookie
2. Query string (localhost//mypage/?lang=es)
3. Route (localhost//pt-BR/mypage)
*/
//trying to obtain culture from cookie
options.RequestCultureProviders.Add(new CookieRequestCultureProvider
{
CookieName = cookieName,
});
//trying to obtain culture from query string e.g. localhost//mypage/?lang=es
options.RequestCultureProviders.Add(new QueryStringRequestCultureProvider
{
QueryStringKey = queryStringKey,
UIQueryStringKey = uiQueryStringKey
});
//trying to obtain culture from route e.g. localhost//pt-BR/mypage
options.RequestCultureProviders.Add(new RouteDataRequestCultureProvider());
});
services.Configure<JsonLocalizationOptions>(Configuration.GetSection("DesignLocal.JsonLocalizer"));
services.AddJsonLocalization();
//services.AddJsonLocalization(options =>
//{
// options.ResourcesPath = "LocalizedData";
// options.ShowResourcePathInDebug = false;
// options.MissingStringPrefix = "!";
// options.ShowDebugInfo = DebugViewOptions.ShowIfResourceMissing;
// options.CacheDuration = TimeSpan.FromSeconds(30);
//});
}
Add Localization configuration section to AppSettings.json to configure Asp.Net RequestLocalizationOptions
Add DesignLocal.JsonLocalizer configuration section to AppSettings.json to configure JsonLocalizer
{
"Localizaion": {
"CookieName": "__uiculture.name",
"FallBackToParentCultures": true,
"QueryStringKey": "lang",
"UIQueryStringKey": "ui-lang",
"SupportedCultures": [
"en",
"es",
"ru"
]
},
"DesignLocal.JsonLocalizer": {
"ResourcesPath": "LocalizedData",
"ShowResourcePathInDebug": false,
"ShowDebugInfo": "ShowIfResourceMissing", //"Hide" | "ShowAlways"
"MissingStringPrefix": "!",
"CacheDurationMinutes": 30
}
}
Ok, there is one trick here. Technically you can add resource files manually, but there is an easier way of doing it.