I have a web application which uses different resource files:
English resources
- CommonResources.resx
- NightResources.resx (resources used when DayTime == DayTime.Night)
- DayResources.resx (resources used when DayTime == DayTime.Day)
- DayTimeResources.resx (resources of NightResources.resx or DayResources.resx)
Dutch resources
- CommonResources.nl.resx
- NightResources.nl.resx (resources used when DayTime == DayTime.Night)
- DayResources.nl.resx (resources used when DayTime == DayTime.Day)
- DayTimeResources.nl.resx (resources of NightResources.nl.resx or DayResources.nl.resx)
Most resources are read from CommonResources.resx or CommonResources.nl.resx, depending on the current language. No problem here.
Conditional resources...
Some resources are conditional. At runtime a value "DayTime" is read from a database. This value determines which resources must be used, either DayResources or NightResources. In my view I use:
@DayTimeResources.Orb
When DayTime == DayTime.Day this must show "sun". When DayTime == DayTime.Night this must show "moon"
When the current language is Dutch and DayTime == DayTime.Day this must show "zon". When DayTime == DayTime.Night this must show "maan"
I have found a solution how to do this. With reflection I runtime change the resource file of class DayTimeResources (which I use in my views).
Here is the code of my test application:
public class MvcApplication : System.Web.HttpApplication
{
private const string LanguageCode = "nl-NL";
private const DayTime CurrentDayTime = DayTime.Day;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
SetCurrentUserLanguage();
ReplaceResourceFile(typeof(DayTimeResources), CurrentDayTime == DayTime.Day ? typeof(DayResources) : typeof(NightResources));
}
private void SetCurrentUserLanguage()
{
CultureInfo cultureInfo = new CultureInfo(LanguageCode);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
}
private void ReplaceResourceFile(Type originalType, Type replaceType)
{
FieldInfo fieldInfo = originalType.GetField("resourceMan", BindingFlags.NonPublic | BindingFlags.Static);
if (fieldInfo != null)
{
ResourceManager resourceManager = new ResourceManager(replaceType.FullName, replaceType.Assembly);
//ResourceSet resourceSet = resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
fieldInfo.SetValue(null, resourceManager);
}
}
For the biggest part, this works. When DayTime == DayTime.Day it shows "sun" and when DayTime == DayTime.Night it shows "moon".
Unfortunately when I change the current (UI) language to Dutch, it still shows "sun" or "moon" and not the translation ("zon" or "maan").
Any idea how to solve this?
Remarkable: when I look at the resource set of the newly created ResourceManager with
ResourceSet resourceSet = resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
it DOES contain the translations.
Maybe there is a better solution for this 'conditional resources problem'. I really would like to hear about it.
(And yes I know you can access a resource like this:
ResourceNamespace.ResxFileName.ResourceManager.GetString("ResourceKey");
but that is not what I want)
Thanks