0

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

RWC
  • 4,697
  • 2
  • 22
  • 29

1 Answers1

0

I have found the problem. I did change the resource manager using reflection, but I also had to change the CultureInfo. Using the following worked:

public class MvcApplication : System.Web.HttpApplication
{
    private const string LanguageCode = "nl-NL";

    private const DayTime CurrentDayTime = DayTime.Night;

    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);
        ResourceManager resourceManager = new ResourceManager(replaceType.FullName, replaceType.Assembly);
        fieldInfo.SetValue(null, resourceManager);
        fieldInfo = originalType.GetField("resourceCulture", BindingFlags.NonPublic | BindingFlags.Static);
        fieldInfo.SetValue(null, CultureInfo.CurrentUICulture);
    }
}
RWC
  • 4,697
  • 2
  • 22
  • 29