问题描述
我有一个以 10 种不同语言国际化的 ASP.NET3.5 (C#) ASPX 页面.
I have an ASP.NET3.5 (C#) ASPX page that is internationalized in 10 different languages.
该页面的结构非常复杂,其中包含由状态机模式驱动的数十个嵌套视图.
The page is very complex in its structured with dozens of nested views driven by a state machine pattern.
我在每个 asp 控件中使用 meta:resourcekey
语法,它允许对隐式资源表达式使用声明性语法.
I am using the meta:resourcekey
syntax in every asp control, which allows to use declarative syntax for Implicit Resource expressions.
我被要求根据一些查询字符串参数标记"页面.品牌化不仅意味着加载不同的 CSS 文件,还意味着拥有不同的文本简介(所有语言).
I have been asked to "brand" the page based on some query string parameter. Branding will mean not just loading different CSS files, but also having different text blurbs (in all languages).
有没有一种简单的方法来交换"resx 文件,而无需为此页面上的数百个文字和图像中的每一个手动获取资源?
Is there an easy way to "swap" resx files without having to get resources manually for each of the hundreds of literals and images that I have on this page?
换句话说,假设我有以下 RESX 文件:
In other words, let's say I have the following RESX files:
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 文件.
myPage.aspx will be looking for resx files named myPage.xx-XX.resx.
有没有办法根据某些值来加载 brand1xxx.resx 文件或 brand2xxx.resx 文件?
Is there a way to load instead either the brand1xxx.resx files or the brand2xxx.resx based on some value?
提前致谢.
推荐答案
你可以使用 自定义文化来达到这个效果.
You can use custom cultures to achieve this effect.
首先,在系统中创建并注册自定义文化,例如:
First, create and register custom cultures in the system, for example:
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();
请注意,您可能希望构建一个简单的工具来自动执行此操作,因为这些文化需要安装在您的应用程序将被编译或执行的每个系统上.需要管理权限才能注册文化.
Note that you might want to build a simple tool to automate this, since those cultures need to be installed on every system where your aplication will be compiled or executed. Administrative rights are needed to be able to register the cultures.
安装文化后,像往常一样创建 resx 文件,但使用自定义文化名称(myPage.aspx.en-US-brand1.resx 等).
Once you have the cultures installed, create resx files like you would normally do, but use the custom culture names (myPage.aspx.en-US-brand1.resx etc).
现在剩下要做的就是根据一些参数设置 System.Threading.Thread.CurrentThread.CurrentUICulture (越早越好,BeginRequest 是一个好地方;或者 Page_PreInit,如果你只想对某些页面这样做):
Now all that's left to do is to set System.Threading.Thread.CurrentThread.CurrentUICulture based on some parameter (the sooner the better, BeginRequest is a good place; or Page_PreInit if you want this only for some pages):
CultureInfo ci = new CultureInfo(Request.QueryString["paramname"]);
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
(设置 CurrentCulture 并不是真正必要的,因为资源是根据 CurrentUICulture 工作的,但是设置这两者允许您进一步自定义每个品牌的页面,例如为每个自定义文化/品牌使用不同的日期/时间格式设置)
(setting CurrentCulture is not really necessary, as resources work in terms of CurrentUICulture, but setting both allows you to further customize the page for each brand, e.g. use different date/time format settings for each custom culture/brand)
一些注意事项:
- 此解决方案为您提供了极大的灵活性,因为正常的文化回退生效 - 如果未找到 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 的异常后立即进行;这将阻止标准的死亡黄页和至少部分异常堆栈的本地化,
- 您可以考虑构建一个服务工具来注册/取消注册/更新文化,尤其是在您预计会频繁更改的情况下,
- 如果您使用基于客户端的文化检测,此解决方案可能会出现问题.
这篇关于如何根据某些参数加载不同的 RESX 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!