C# 使用ResourceManager和Reflection获得正确的翻译

C# 使用ResourceManager和Reflection获得正确的翻译,c#,translation,system.reflection,resourcemanager,C#,Translation,System.reflection,Resourcemanager,我有一个使用不同资源文件的web应用程序: 英语资源 CommonResources.resx NightResources.resx(日间==日间.Night时使用的资源) DayResources.resx(日间==日间.Day时使用的资源) DayTimeResources.resx(NightResources.resx或DayResources.resx的资源) 荷兰资源 CommonResources.nl.resx NightResources.nl.resx(日间==日间.

我有一个使用不同资源文件的web应用程序:

英语资源
  • CommonResources.resx
  • NightResources.resx(日间==日间.Night时使用的资源)
  • DayResources.resx(日间==日间.Day时使用的资源)
  • DayTimeResources.resx(NightResources.resx或DayResources.resx的资源)
荷兰资源
  • CommonResources.nl.resx
  • NightResources.nl.resx(日间==日间.Night时使用的资源)
  • DayResources.nl.resx(日间==日间.Day时使用的资源)
  • DayTimeResources.nl.resx(NightResources.nl.resx或DayResources.nl.resx的资源)
大多数资源都是从CommonResources.resx或CommonResources.nl.resx读取的,具体取决于当前语言。没问题

条件资源。。。 有些资源是有条件的。在运行时,从数据库中读取值“Daily”。此值确定必须使用哪些资源,DayResources或NightResources。在我看来,我使用:

@DayTimeResources.Orb
When Day==Day。Day必须显示“sun”。当白天==白天。夜晚必须显示“月亮”

当当前语言为荷兰语且Day==Day.Day时,必须显示“zon”。当昼间==昼间。夜间必须显示“maan”

我已经找到了一个解决方法。通过反射,我可以在运行时更改DayTimeResources类的资源文件(我在视图中使用它)

以下是我的测试应用程序的代码:

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);
        }
    }
在很大程度上,这是可行的。当白天==白天时,白天显示“太阳”,当白天==白天时,夜晚显示“月亮”

不幸的是,当我将当前(UI)语言更改为荷兰语时,它仍然显示“sun”或“moon”,而不是翻译(“zon”或“maan”)

你知道怎么解决这个问题吗

值得注意的是:当我用

ResourceSet resourceSet = resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
它确实包含翻译

对于这个“条件资源问题”,也许有更好的解决方案。我真的很想听一听

(是的,我知道您可以访问这样的资源:

ResourceNamespace.ResxFileName.ResourceManager.GetString("ResourceKey");
但这不是我想要的)


谢谢,我找到问题了。我确实使用反射更改了资源管理器,但我还必须更改CultureInfo。使用以下方法可以:

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);
    }
}