摘要:本文将通过一个实际案例来详细剖析如何实现一个ASP.NET 2.0网站开发过程中的全球化与本地化问题。
一、简介
全球化和本地化是每一位开发者在创建全球化产品或应用程序时必须清楚的两个重要的慨念。尽管有许多文章对这个题目作过较好的解释,但是我一直没有看到一篇全面而综合地讨论关于全球化/本地化的所有重要概念的文章。本文旨在通过一个具体案例来详细分析使用ASP.NET2.0开发一个web应用程序时所涉及到的全球化问题。
二、背景理论
全球化是应用程序开发中某一阶段的任务,其目的是使程序能够跨多个文化地区可用而不必顾及语言和地区性差别。例如,你在开发一个小型库存管理程序,而你生活在例如英格兰这样一个以英语为主要语言的地区。现在,如果你想把你的程序卖到另一个不同国家,比方说是德国,那么你需要确保你的程序以德语显示并实现输入。
本地化是使用一种地区特定的文化和语言来创建内容、输入和输出数据的过程。文化将会影响日期显示设置(如是mm/dd/yyyy还是dd/mm/yyyy),货币显示格式等。现在,确保我们的程序能够被本地化的过程称为国际化或全球化。用更简单的术语来说,全球化能够被定义为一组活动,通过这一活动,可以确保我们的程序能够运行在使用不同语言和文化的地区。
因此,全球化是与内在代码的改变相关联的以便支持这样的改变,如使用资源文件等;而本地化是使用一种特定的文化和地区性信息的过程,以便该程序能够使用本地的语言和文化。这意味着要把字符串翻译成一个特定的本地的语言;为此,要把语言特定的字符串放到资源文件中。一般地,应该从主构建和代码开发阶段就开始考虑全球化问题,而本地化通常在以后才实现。
三、 实现ASP.NET 2.0网站的全球化
让我们从一个简单的示例开始。为了解释本地化并使事情尽可能简单,我使用ASP.NET和C#创建了一个称为TestSite的新网站(详见本文下载的源码);我添加了一个MasterPage和一个缺省页面。这个缺省页面中含有一个TextBox和一个Calendar控件;该TextBox控件有一个描述货币的双精度型实数。在本例中,我们会看到随着用户选择不同的语言货币格式发生相应的变化。当我运行该应用程序时,此缺省页面看起来如下所示:
我已经出版了这个测试web应用程序,你可以在下列URL处看到它的功能版本:http://63.134.215.124/testsite/default.aspx
四、 文化和本地化
首先,让我先解释一下文化和本地化。
一般地,语言也依赖于地理位置。例如,法语既是法国人的语言也是加拿大人的语言(除此之外,还有其它许多国家也说法语)。但是从语言角度来讲,加拿大法语不同于法国法语。同样,在美国英语和英国英语之间也存在一定的区别。因此,语言常常需要与说该语言的特定地区相联系,并且这是通过使用本地化(语言+地理位置)实现的。
例如,fr是法语语言的代码,而fr-FR意味着法国使用的法语。因此,fr仅指定了这种语言,而fr-FR才实现了本地化。同样,fr-CA定义另一个代表加拿大法语和文化的本地化。如果我们仅仅使用fr,那么它仅代表是一种中立性质的文化(也即是,地区中立)。
那么,我们如何定义或改变当前文化呢?
在.NET FCL(框架类库)的CultureInfo类中存在两个属性,我们可以通过重载该类的构造器来对它们进行设置,然后使用它来改变当前执行线程的文化:
1.UICulture:取得/设置当前执行线程的用户接口。这个属性帮助运行时刻从一个特定的资源文件(我们将在后面看到)中加载资源字符串。这个属性能够使用中立文化,也可以是本地化。例如:
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr");
或:
Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-CA");
2.Culture:取得/设置地区特定的文化和货币、日期等的格式。这个属性需要语言也需要位置(本地化)。
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-A"); //正确,因为我们已经给出了本地化
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr"); //错误,无法工作
有时,我们需要一种不属于任何语言或本地化的文化,对于任何地区/语言都不变。为此,我们可以使用CultureInfo.InvariantCulture属性。这一属性在内部系统处理期间使用;此时,要求是文化独立的,或者存储不需要被直接显示给终端用户的数据。
UICulture和Culture属性都能够在Web.Config文件的<GLOBALIZATION>属性中进行定义。另外,它们还能够在页面级上被指定。但是,我们不想硬编码这些值而是喜欢动态地设置它们。由上面可知,我们还能够使用Thread.CurrentThread.CurrentCulture和Thread.CurrentThread.CurrentUICulture属性以编码方式得到/设置这些值。因此,我们将在本应用程序中使用这些属性。
五、本地化切换 现在,回到我们的应用程序中来,我们需要一种方法实现本地化切换。为此,存在两种方法:
1.使用浏览器设置:在IE中,用户可以通过使用"Internet Options->General->Languages"来改变文化。为此,我们需要把Culture和UICulture都设置为auto并且把enableClientBasedCulture设置为true,如下所示:
< GLOBALIZATION culture="auto" uiculture="auto" enableClientBasedCulture=""true"" />
2.用户指定的设置:我们能够向用户提供一个选项以便其在运行时刻指定和改变文化和语言。这是推荐的方法,因为有时浏览器本身可能没有提供用户特定的语言集(例如一个法语旅游者可能在印度上网)。而且,有时经由浏览器修改语言设置将会被阻断。
现在,我们使用第二种推荐的方法,我在MasterPage上部(在一个面板控件内)创建了一个节;此处,我使用了一个具有这些语言选项的下拉列表框以便让用户选择一种特定的本地化表达。
在本示例中,仅为了说明问题,我仅使用了四种语言选项:
Hindi,American English,British English和French。
为了实现我的应用程序的全球化,我的目标是:无论用户何时选择一种特定的本地化语言,下列都应该发生:
1.所有内容都应该是本地化的:这意味着,所有字符串和文本应该以选择的语言和本地化显示。
2.每个控件的标题(/内容)也应该以本地语言显示文本。
3.日期和货币格式化应该根据选择的本地化发生。
4.所有显示给用户的消息应该是使用本地的语言。
为了达到以上目的,你首先要确保从代码中取出此内容并把它放在单独的资源文件中,在.NET中这是一些具有.resx扩展名的简单的XML文件。
由于这些内容将因语言不同而有所不同,所以,我们针对每一种文化(语言)各自建立了相应的资源文件。每一个这样的文件中都提供了Name和Value两个域。下面是在两个资源文件中的示例入口;在此,假定我们必须输入一个字符串"Welcome":
1.添加一个新的资源文件并命名它为TestSiteResource.resx,并且使用VS编辑器打开它。在Name域输入"Banner",在Value域输入"Test Website for Localization"。这个资源文