I have an ASP.NET MVC 5 WEB Application running under a website in IIS 8 where I need to change language programmatically at runtime by a user preference that I read from a DB and store in a session variable, and this value can change during runtime with a dropdown.
The problem is language resources sometimes do not change, despite the CurrentCulture does and the worse thing is they freeze at an application level making that all the other user sessions to freeze to that language too and will show only in all application sessions the same language in which is stuck regardless their preference or if they even try to change their language at runtime which when is working normally forces CurrentThread.CurrentCulture to change.
I use a hidden text in the views to track what the CurrentThread.CurrentCulture was and is changing as expected so the problem must be some place else.
This is the razor block I use to inspect CurrentCulture
<div style="display:none; visibility: hidden;">Thread
@System.Threading.Thread.CurrentThread.CurrentCulture</div>
And at runtime when the language or resx are freezed/stucked at an application level the value is indeed the correct and selected but it does not match the language being displayed in the views and it wont work normally until I make for example a change in the web.config or restart the application and then it works fine for a while but do not last too much time.
<div style="display:none; visibility: hidden;">Thread en-US</div>
The problem is that this happens at an application level for all user sessions and the CurrentCulture is actually changing as expected when the application is working normally and whenever is restarted this does not happen but somehow every certain time something triggers during user sessions to freeze of the language of all current sessions and even new sessions.
I have tried placing the change of culture logic in the razor views, action filters and a base controller too but that did not solve the problem, previously I had a base controller which all my controller inherited and logic at Global.asax.cs to change and determine culture.
My current approach was to remove the base controller and using in both Global.asax.cs Application_AcquireRequestState (I´ve tried too using Application_BeginRequest but somehow is too earlier in lifecycle) and an Action Filter.
This is in Global.asax.cs
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
if (Context.Session != null && Context.Session["CultureName"] != null)
{
string cultureName = Context.Session["CultureName"].ToString();
CultureInfo cultureInfo = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
And my Action Filter like this
public class CultureActionAttribute : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
string cultureName = null;
string tenant = filterContext.RouteData.Values["Tenant"] as string;
if (!String.IsNullOrWhiteSpace(tenant))
{
TenantService tenantService = new TenantService(tenant);
cultureName = CultureHelper.GetImplementedCulture(tenantService.Tenant.LanguageCulture);
tenantService.Unit.Dispose();
}
//Logic to override cultureName value by getting the user preference language
CultureInfo cultureInfo = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
}
And I added it at FilterConfig
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new CultureActionAttribute());
//
}
I even tried to use ClearCachedData when is the user changes culture.
Thread.CurrentThread.CurrentCulture.ClearCachedData();
I think this might be relating to caching or pool recycling but I am out of ideas of what to try next.
I am not using any globalization tag at web.config.
The value in traced in views of CurrentThread.CurrentCulture is always correct what is wrong is the freezing with the use of resources.
Resources are consistent with the practice of placing them in a separate, dedicated standard folder and to use PublicResXFileCodeGenerator to make them public to able to compile and be accessible to Controllers, Views, etc
Resources folder
Can anyone please provide me another choice to try or thought about what might I be doing wrong or what else can I try to make resources to work consistently.