【问题标题】:How to load different RESX files based on some parameter如何根据某些参数加载不同的 RESX 文件
【发布时间】:2011-04-07 19:34:57
【问题描述】:

我有一个以 10 种不同语言国际化的 ASP.NET3.5 (C#) ASPX 页面。

该页面的结构非常复杂,其中包含由状态机模式驱动的数十个嵌套视图。

编辑:我在每个 asp 控件中使用meta:resourcekey 语法,它允许对隐式资源表达式使用声明性语法。

我被要求根据一些查询字符串参数“标记”页面。品牌化不仅意味着加载不同的 CSS 文件,还意味着拥有不同的文本简介(所有语言)。

有没有一种简单的方法来“交换”resx 文件,而无需为此页面上的数百个文字和图像中的每一个手动获取资源?

换句话说,假设我有以下 RESX 文件:

brand1_myPage.aspx.en-US.resx
brand1_myPage.aspx.de-DE.resx
brand1_myPage.aspx.fr-FR.resx

brand2_myPage.aspx.en-US.resx
brand2_myPage.aspx.de-DE.resx
brand2_myPage.aspx.fr-FR.resx

myPage.aspx 将寻找名为 myPage.xx-XX.resx 的 resx 文件。

有没有办法根据某些值来加载 brand1xxx.resx 文件或 brand2xxx.resx 文件?

提前致谢。

【问题讨论】:

    标签: c# .net asp.net internationalization resx


    【解决方案1】:

    你可以使用custom cultures来实现这个效果。

    首先,在系统中创建并注册自定义文化,例如:

    CultureAndRegionInfoBuilder builder = new CultureAndRegionInfoBuilder("en-US-brand1", CultureAndRegionModifiers.None);
    CultureInfo parentCI = new CultureInfo("en-US");
    RegionInfo parentRI = new RegionInfo("en-US");
    builder.LoadDataFromCultureInfo(parentCI);
    builder.LoadDataFromRegionInfo(parentRI);
    builder.Parent = parentCI;
    // set other properties of the custom culture (CultureEnglishName, CultureNativeName, possibly other ones)
    // ...
    builder.Register();
    

    请注意,您可能希望构建一个简单的工具来自动执行此操作,因为这些文化需要安装在您的应用程序将被编译或执行的每个系统上。需要管理权限才能注册文化。

    安装文化后,像往常一样创建 resx 文件,但使用自定义文化名称(myPage.aspx.en-US-brand1.resx 等)。

    现在剩下要做的就是根据一些参数设置 System.Threading.Thread.CurrentThread.CurrentUICulture (越早越好,BeginRequest 是一个好地方;或者 Page_PreInit,如果你只想对某些页面这样做):

    CultureInfo ci = new CultureInfo(Request.QueryString["paramname"]);
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;
    

    (设置 CurrentCulture 并不是真正必要的,因为资源是根据 CurrentUICulture 工作的,但是设置这两者允许您进一步自定义每个品牌的页面,例如为每个自定义文化/品牌使用不同的日期/时间格式设置)

    一些注意事项:

    • 此解决方案为您提供了极大的灵活性,因为正常的文化回退生效 - 如果未找到 en-US-brandX 的条目,运行时将回退到 en-US 等等;如果品牌大多相似,这可以大大减少重复的 resx 条目,因为您只能将一些条目放在父(en-US)resx 文件中,
    • 您可以创建更多级别的继承文化,例如 en-US-brandX-variantY,
    • 所有访问资源的方法都按预期工作,
    • 更改工作线程的文化意味着如果您将文化设置为 de-DE-brandX 并且您在操作系统中安装了 de-DE 本地化,您将收到本地化异常消息,
    • 由于上述原因,您可能希望在 Application_Error 中将当前 (UI) 区域性重置为 CultureInfo.InvariantCulture,或者最好在捕获到您知道会导致 Application_Error 的异常后立即进行;这将阻止标准的死亡黄页和至少部分异常堆栈的本地化,
    • 您可以考虑构建一个服务工具来注册/取消注册/更新文化,尤其是在您预计会频繁更改的情况下,
    • 如果您使用基于客户端的文化检测,此解决方案可能会出现问题。

    【讨论】:

      【解决方案2】:

      如果您在代码中像这样引用资源:Resources.brand1_myPage.WelcomeMessage,那么这可能会很困难。

      但您也可以通过编程方式检索资源:GetGlobalResourceObject ("brand1_myPage", "WelcomeMessage")。在这里,您可以对资源文件名进行一些操作。

      【讨论】:

      • 我既没有使用GetGlobalResourceObject,也没有使用GetLocalResourceObject。每个 ASP 控件都有一个内置的 meta:resource 属性,该属性会自动从关联的 RESX 文件加载。例如,如果我有以下 ASP 标签:<asp:Literal ID="someLit" runat="server" meta:resourceKey="someLitResource">,然后在我定义了someLitResource.Text 的 10 个不同的 RESX 文件中,当前语言的内容已经自动加载。
      猜你喜欢
      • 2019-04-16
      • 2021-12-30
      • 1970-01-01
      • 2012-08-10
      • 1970-01-01
      • 2014-03-18
      • 2015-01-11
      • 2015-07-01
      • 2021-12-21
      相关资源
      最近更新 更多