【凌风雨寒】解析Asp.net中资源本地化的实现
上一篇 / 下一篇 2008-07-22 13:54:58 / 个人分类:.net
本文将从Asp.net实现资源全球化和本地化的基本概念入手,阐述在Asp.net1.1和Asp.net2.0中实现全球
化和本地化的步骤、方法。
一.基本概念
1.为什么要实现资源的本地化?
我们的站点可能为全球各个国家和地区的人所浏览,每个国家和地区的人都有自身的语言文化
特点。就拿咱们伟大的祖国为例,中国大陆用简体中文,港澳台则使用繁体中文。另外各个国家对于货
币、数字、日历等信息的表达格式各有不同,我们国家多使用年月日的格式,而美国则是月日年。诸如
此类的区别林林总总,我也就不多举例了。为了给我们的网站浏览者更好的用户体验,我们应该提供一
个全球化的解决方案,只要用户选择了他的语言和区域,站点就按照他的语言文化习惯来展现页面信息
,这个过程可以叫做本地化。
2.区域性、固定区域性、非特定区域性、特定区域性
区域性名称遵循 RFC 1766 标准,格式为“-”,其中 是从 ISO 639-1 派生的由两个小写字母
构成的代码, 是从 ISO 3166 派生的由两个大写字母构成的代码。例如,美国英语为“en-US”。在双
字母语言代码不可用的情况中,将使用从 ISO 639-2 派生的三字母代码;例如,三字母代码“div”用
于使用 Dhivehi 语言的区域。某些区域性名称带有指定书写符号的后缀;例如“-Cyrl”指定西里尔语
书写符号,“-Latn”指定拉丁语书写符号。举例:
ITPUB个人空间lO['zf1]0k
区域性名称
区域性标识符
语言-国家/地区
zh-CN
0x0804
中文-中国
zh-TW
0x0404
中文-台湾
zh-CHS
0x0004
简体中文
zh-CHT
0x7C04
繁体中文
en
0x0009
英语
en-US
0x0409
英语-美国
en-GB
0x0809
英语-英国
uz-UZ-Cyrl
0x0843
乌兹别克语(西里尔语)- 乌兹别克斯坦
uz-UZ-Latn
0x0443
乌兹别克语(拉丁)- 乌兹别克斯坦
&LQ,K$zg0 固定区域性不区分区域性。可以使用空字符串 ("") 按名称或者
/~l$?0Z[eX0CultureInfo Invc = CultureInfo.InvariantCulture;这两行代码的作用相同,目的是获得固定区域性
实例。
比如你现在要对一个DateTime的实例dateTime执行dateTime.ToString()方法。这个方法实际是
使用你当前线程的CurrentCulture作为默认的区域性,根据这个区域性将日期实例转化为相应的字符串
形式。那么如果我们此时不需要它按照线程或系统的区域性进行ToString操作,那么我们应该用这个方
法dateTime.ToString(“G”, CultureInfo.InvariantCulture)或者dateTime.ToString(“G”,
DateTimeFormatInfo.InvariantInfo)。
非特定区域性是与某种语言关联但不与国家/地区关联的区域性。特定区域性是与某种语言和某
个国家/地区关联的区域性。例如,“en”是非特定区域性,而“en-US”是特定区域性。注意,“zh-
CHS”(简体中文)和“zh-CHT”(繁体中文)均为非特定区域性。
区域性有层次结构,即特定区域性的父级是非特定区域性,而非特定区域性的父级是
InvariantCulture。CultureInfo类的Parent属性将返回与特定区域性关联的非特定区域性。如果特定区
域性的资源在系统中不存在,或因其它原因不可用,则使用非特定区域性的资源;如果非特定区域性的
资源也不可用,那么使用主程序集中嵌入的资源。
3.实现本地化常用的类型、属性和方法
CultureInfo类表示有关特定区域性的信息,包括区域性的名称、书写体系和使用的日历,以及
有关对常用操作(如格式化日期和排序字符串)提供信息的区域性特定对象的访问。CultureInfo类的实
例化一般有两个途径,如下所示:
.b*k(Ly#vj*s0CultureInfo culture = CultureInfo. CreateSpecificCulture (name);ITPUB个人空间Y:H#ALcQqBRQ
CultureInfo culture = new CultureInfo(name);
二者的区别是,使用第一种方法,只能创建固定区域性或特定区域性的CultureInfo实例。如果
name为空字符串,则建立固定区域性的实例,如果name为非特定区域性,那么建立name 关联的默认特定
区域性的 CultureInfo实例。第二种方法,则是建立一个name所指定的区域性的CultureInfo实例,它可
以是固定的,非特定的或特定区域性的。
Thread类的CurrentCulture属性用来获取或设置当前线程的区域性。它必须被设置为特定区域
性。Thread.Curr
entThread.CurrentCulture = new CultureInfo("en-US");如果Thread.CurrentThread.CurrentCulture
= new CultureInfo("en ");就会报错!
Thread类的CurrentUICulture属性用来获取或设置资源管理器使用的当前区域性以便在运行时
查找区域性特定的资源。这里的资源管理器可以关联为ResourceManger类。ITPUB个人空间6] Gxs"Pzw
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en");
{
wL-f+_
V2e7l+xS0Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
ResourceManger类可以查找区域性特定的资源,当本地化资源不存在时提供代用资源,并支持
资源序列化。常用的ResourceManager的构造函数是public ResourceManager(string,Assembly)。其含
义是初始化 ResourceManager类的新实例,它使用指定的根名称从给定的Assembly中查找资源文件。所
谓根名称是例如名为“MyResource.en-US.resources”的资源文件的根名称为“MyResource”。在根名
称的表达中可以加上命名空间,如“MyWebSite.Resource.UserFolder. MyResource”。而Assembly可以
是需要调用资源文件的页面所在的Assembly,如typeof(MyPage).Assembly。ResourceManager类的
GetString方法用来获得资源文件中的指定键的值。举例:当已设置了线程的CurrentUICulture属性之后
按如下方法。
D$xT],i1~r9_0ResourceManager rm = new ResourceManager("items", Assembly.GetExecutingAssembly());
0L
`7x0Q&^UB%L&E#o0String str = rm.GetString("welcome");
如果想按照指定的区域性来获得资源则按照如下写法:ITPUB个人空间 l\_2jk7VO8}
ResourceManager rm = new ResourceManager("items", Assembly.GetExecutingAssembly());
0K/q
y
ph#g0CultureInfo ci = Thread.CurrentThread.CurrentCulture;ITPUB个人空间'^
G{
rV
String str = rm.GetString("welcome",ci);
ITPUB个人空间0_x7YV0r!G
二.在Asp.net1.1中实现资源本地化
首先应在网站项目WebTest中建立一个Resource文件夹,在这个文件夹中存放整个项目公用的资
源文件。比如我们建立了以下三个资源文件:MyResource.en.resx,MyResource.en-
US.resx,MyResource.zh-CN.res。每个资源文件中都有两个键值对,键值为State和Address。在需要使
用资源文件的页面MyPage.aspx中调用资源文件,如下所示:
c U h J2N'a p*v
aY,dx0Thread.CurrentThread.CurrentCulture= CultureInfo.CreateSpecificCulture("zh-CN");ITPUB个人空间+?&Qh%L(~9q-?.MB
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;ITPUB个人空间-@&Vv B l0_
ResourceManager rm = new ResourceManager("WebTest.Resource.MyResource", typeof
(MyPage).Assembly);
7H)W;Q A.q!E!nH7y0Label1.Text = rm.GetString("State");ITPUB个人空间9W0d&v_X1^+A
Label2.Text = rm.GetString("Address");
好了,这个时候Label1和Label2就按照MyResource.zh-CN.resx文件中的规定显示“州”和“地址”。以
上是一个最基本最简单的本地化方法,这里隐含着一些问题,我们来逐一解决并优化该方法。
1. 如何获得用户的默认区域性
通过用户浏览器“属性”->“语言”选项里的设置,取最上面那条作为用户的默认语言。ITPUB个人空间?`
WTt+iF
Ep
CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);