Reputation: 4993
I have an ASP.NET Web API application which should react to user's Accept-Language header appropriately.
Currently, the strings are stored in the resx and accessed in compile-safe manner through Visual Studio's generated class. What I would like to do is to keep the current approach and create satellite assemblies for each translated version of resx. Then to analyze the user's Accept-Language header to see what languages a user accepts and load the resources for the requested language from the satellite assembly.
I suppose I could implement all this behavior myself by creating a set of language-specific ResourceManager
objects with the help of the ResourceSet
but then it would not be possible to keep the compile-time safety, since Visual Studio takes care of automatically updating the class for resx file.
What would be the best way to pick the localized language resource dynamically?
Upvotes: 8
Views: 14332
Reputation: 15410
From reading your question, I don't see anything that ASP.NET doesn't offer automatically. You can configure your ASP.NET (whether WebForms or MVC) to use the accept-language
request header and set the appropriate UICulture (which will impact which satellite assembly is loaded by ResourceManager) and Culture (which will impact locale-dependent formatting and parsing such as dates and numbers) appropriately.
To configure your app to use the accept-language
list to set both UICulture and Culture for each request, (as per this MSDN page), configure your web.config like this:
<globalization uiCulture="auto" culture="auto" />
There is also an equivalent configuration setting per page.
Then, as per the Resource Fallback process, if your app includes a satellite assembly for the matching culture (or, failing that, its parent neutral culture), it will be used by the Resource Manager. If not, then your default resources will be used (English if that's your base language).
Upvotes: 11
Reputation: 42497
You could write an HttpModule
that detects the language header, and sets the current thread culture.
public class LanguageModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
var application = sender as HttpApplication;
var context = application.Context;
var lang = context.Request.Headers["Accept-Language"];
// eat the cookie (if any) and set the culture
if (!string.IsNullOrEmpty(lang))
{
var culture = new System.Globalization.CultureInfo(lang); // you may need to interpret the value of "lang" to match what is expected by CultureInfo
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
}
}
}
ResourceManager
et al will figure out the correct localized version to use from the thread culture.
Upvotes: 4