We are getting an strange behavior in multi-language development in ASP.NET Core Razor pages based application, IStringLocalizer object that we are using in .cshtml pages is recognizing the currently selected culture and translating all elements correctly those are on .cshtml file as per selected culture's resource files, but same object used inside page models (i.e. .cshtml.cs) files, is always translating into browser default language when requested through AJAX GET or POST method. Its not able to recognize currently selected culture. Used QueryStringRequestCultureProvider.
This is what working in .cshtml page and its translating as per the culture selected in String
@page
@inject IStringLocalizer<IndexModel> localizer
@model IndexModel
@{
ViewData["Title"] = "Home page";
var requestCultureFeature = HttpContext.Features.Get<IRequestCultureFeature>();
var requestCulture = requestCultureFeature.RequestCulture;
}
<div class="text-center">
<h1 class="display-4">@localizer["Welcome"]</h1>
</div>
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-3.3.1.min.js"></script>
<script lang="javascript">
$(document).ready(function () {
$("#btnnsubmit").click(function () {
var obj = {};
obj.name = "name";
//url
$.ajax({
type: "Get",
url: '/Index?handler=callingAjax',
data: obj,
dataType: "html",
contentType: "application/json; charset=utf-8",
success: function () {
debugger;
},
error: function () {
}
});
});
});
</script>
This is what I have done in page models (i.e. in .cshtml.cs pages) and it always translating into browser's default language.
public class IndexModel : PageModel
{
public string Message { get; set; }
private readonly ILogger log;
private readonly IStringLocalizer<IndexModel> localizer;
public IndexModel(ILogger<IndexModel> log, IStringLocalizer<IndexModel> _localizer)
{
this.log = log;
localizer = _localizer;
}
public void OnGet()
{
// Called on page load without AJAX
//Localization is working here, gives translation based on selected
//language
string str = _localizer["InvalidLoginAttempt"];
}
public IActionResult OnGetCallingAjax()
{
int MaxThreads = 1;
// Called using AJAX
//Localization is not working here, always gives translation based on
//browsers default language,
string str1 = _localizer["InvalidLoginAttempt"];
string message = "SUCCESS";
return new JsonResult(new
{
Error = false,
Message = message,
// lstlang = lstlanguage
});
}
}
Below are the Startup file setting.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<RequestLocalizationOptions>(options =>
{
var supportedCultures = new[]
{
new CultureInfo("de"),
new CultureInfo("fr"),
new CultureInfo("en"),
new CultureInfo("nl"),
};
options.DefaultRequestCulture = new RequestCulture("de");
options.SupportedCultures = supportedCultures;
options.SupportedUICultures = supportedCultures;
options.RequestCultureProviders = new List<IRequestCultureProvider>
{
new QueryStringRequestCultureProvider(),
new CookieRequestCultureProvider()
};
});
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(30);
});
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => false;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddSession(options => {
options.IdleTimeout = TimeSpan.FromMinutes(30); //default is 20 min
});
services.AddLocalization(options => options.ResourcesPath = "Resources");
services.AddMemoryCache();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix);
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddLog4Net();
Log4NetFilters.Set( // filter out the standard log messages with source "Microsoft"
source: "Microsoft",
filteredLogLevel: LogLevel.Information);
ILogger logger = loggerFactory.CreateLogger<Program>();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseStaticFiles();
//app.UseRouting();
app.UseSession();
app.UseCookiePolicy();
app.UseHttpsRedirection();
var localizationOptions = app.ApplicationServices.GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(localizationOptions);
app.UseMvc();
}
same object used inside page models (i.e. .cshtml.cs) files, is always translating into browser default language.Do you mean that using same code snippetlocalizer["ContactUs"]from .cshtml and .cshtml.cs, which return different localized value for same indexer? I did a test but can not reproduce same issue. If possible, you can share a reproducible sample, we would help troubleshoot the issue based on that. - Fei HanIStringLocalizer<IndexModel> localizer;being used in both .cshtml and .cshtml file. - yadavr