65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 .NET 构建国际化应用程序 – 第 1 部分

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (14投票s)

2003年10月22日

7分钟阅读

viewsIcon

72149

downloadIcon

1

本文是多部分系列文章的第一篇,讨论如何使用 .NET 编写面向世界的应用程序。

引言

您的 Web 应用程序用户通常会遍布许多地理区域,每个区域都有其显示和处理文本的方式。一个真正面向国际的 Web 应用程序应该以一种所有用户,无论来自哪个地理区域,都能以相同的舒适度工作并看到他们能理解的内容的方式来编写。本文是多部分系列文章的第一篇,讨论如何使用 .NET 编写此类应用程序。

创建国际化应用程序绝非易事。通常,为了使应用程序能够提供本地化的内容,它必须考虑以下几个方面:

  1. 标签和消息
  2. 日期和时间格式
  3. 数字和货币格式
  4. 日历
  5. 字体
  6. 排序以及许多其他方面

微软发布了一个精彩的、循序渐进的资源 《面向世界的应用程序指南》,它用大量的示例和解释阐述了上述所有方面。该链接清楚地解释了开发人员容易混淆并经常互换使用的术语:全球化 (Globalization)本地化 (Localization)。我不想在此重述内容,但我在这篇文章中所做的是用一些 ASP.NET 特有的实现细节和注意事项来补充这些内容。

.NET 与全球化

NET 框架在 `System.Globalization` 命名空间中提供了一组丰富的类,这些类使得开发面向世界的应用程序相对容易。其中最主要的类是 `CultureInfo`,我将主要使用它。在深入研究文化之前,让我们先看看“文化”是什么。文化可以被视为一组特定语言和/或地区的设置和约定。也就是说,文化决定了日期、时间和货币格式等。文化可以分为三类:

  • 不变 (Invariant):这仅与英语相关,与任何地区无关。通常,可用于以与文化无关的方式存储数据。因此,不应将其用于用户界面元素。
  • 中性文化 (Neutral culture):它与语言相关,但与地区无关。它仅可用于与语言相关的方面,而不能用于日期、时间和货币格式。例如,fr 等。
  • 特定文化 (Specific culture):它与语言和地区相关,因此可用于所有类型的格式设置。例如,en-US、de-De 等。

CultureInfo 封装了一组特定于特定文化的设置。NET 框架提供了大约 200 种文化的实现,可以通过使用 `GetCultures` 共享方法来枚举它们。在本文中,我将考虑开发面向世界的应用程序的两个方面:选择文化的方法以及标签和消息的处理。

选择文化

第一步是选择需要显示数据的语言(或文化)。为此,您可以考虑许多选项。其中之一是从浏览器获取用户的语言偏好。这可以通过访问 `Request` 对象的 `Languages` 集合来获得。例如,`Request.Languages(0)` 获取用户的首选语言(`Languages` 是一个根据用户偏好排序的集合)。下图显示了 Web 应用程序用户如何在浏览器中设置此偏好。在下面的示例中,请求头将包含用户的语言偏好,即英语(美国),后跟印地语。

第二个选项是在用户界面中为用户提供明确的选项,例如组合框等。当您只支持有限的几种文化并限制用户选择其中一种时,此选项可能更好。下面的代码示例创建了一个下拉列表,让用户有机会从 .NET 支持的所有文化中选择一种文化。

For Each culture In CultureInfo.GetCultures(CultureTypes.SpecificCultures)
    Dim item As New ListItem
    item.Value = culture.Name
    item.Text = culture.DisplayName
    cboAllCultures.Items.Add(item)
Next

下一步是将上述两个选项中的一个转换为 ASP.NET 页面中的特定 `CultureInfo` 实例。更具体地说,我们需要设置应用程序线程的 `CurrentCulture` 和 `CurrentUICulture` **属性。 `CurrentCulture` 属性会影响日期、货币、时间、日历等的显示(或格式)。 `CurrentUICulture` 值决定了 **资源管理器 (Resource Manager)** 需要加载的资源。通常,这些资源是用户界面元素所需的标签和消息(我将在下一节详细介绍)。下面的代码示例将线程的 `CurrentUICulture` 和 `CurrentCulture` 值设置为下拉列表中选择的值。

With Thread.CurrentThread
    .CurrentUICulture = New CultureInfo(cboAllCultures.SelectedValue)
    .CurrentCulture = .CurrentUICulture
End With

标签和消息

这是本地化的第一个主要步骤之一。它基本上涉及以特定语言创建和显示标签和消息。为了实现这一点,我们需要将应用程序显示的文本存储在单独的文件中,称为资源文件。资源文件可以被视为特定语言的标签、消息和其他资源的集合。我不会过多解释资源文件,因为我最近偶然发现了一篇发布在 CodeProject 上的文章,它正是介绍这个的:多语言应用程序。尽管这篇文章考虑了 Windows 应用程序的本地化,但其中大部分内容也适用于 Web 应用程序。总之,要点如下:

  • 将资源存储在单独的文件(*`.Resx`*)中。对于每种支持的语言(文化),都需要创建一个资源文件。
  • 从资源文件创建 **程序集 (satellite assemblies)**。使用 VS.NET,这个过程相当简单。顺便说一句,程序集是只包含资源而不包含代码的程序集。
  • 使用 `ResourceManager` **类**在运行时获取特定资源。

现在,您可能会提出一个问题——运行时如何选择正确的(特定于文化的)资源?我们应该为它编写代码吗?答案是否定的,这由 `ResourceManager` 自动完成,线程的 `CurrentUICulture` 属性就是为此目的而使用的。有关此过程的详细信息,请参阅 此处 (MSDN)。下一个重要问题是——我们在资源文件中存储什么?它们可以是输入元素旁的标签,如“名字”、“地址第一行”等,描述性注释或任何类型的文本,页面和表格标题,窗口标题,图像替代文本等等。本质上,所有显示文本给用户的地方。话虽如此,另一个需要考虑的领域是错误消息。这些可以是作为服务器验证/处理一部分显示的消息,也可以是通过客户端脚本显示的消息。下面是一些示例:

服务器端:在这里,我从资源文件中获取 `RequiredFieldValidator` 的错误消息。

rfvCity.ErrorMessage = rm.GetString("msg_MandCity")

客户端 (浏览器):这稍微棘手一些,因为所有消息都必须在脚本中可用。可以通过使用全局脚本变量来存储错误消息来实现这一点。下面的代码片段对此进行了演示。

Dim sbScript As New StringBuilder
sbScript.Append("<script language="'javascript'">")

sbScript.Append(Environment.NewLine)
sbScript.Append("var msgMandFName = '")
sbScript.Append(rm.GetString("msgMandFName"))
sbScript.Append("';")
sbScript.Append(Environment.NewLine)
sbScript.Append("</script>")
RegisterStartupScript("MessageBlock", sbScript.ToString)

使用该消息的客户端脚本函数(在此情况下为必需检查)可能看起来像

function submitForm()
{
    if(document.forms[0].elements["txtFName"] == "")
    {
        alert(msgMandFName);
        return false;
    }
}

您还可以将图像包含在资源文件中。当图像本身包含特定于文化的内容或文本时,此功能非常方便。我在一个示例中遇到的另一个例子是将国旗图像存储在资源文件中!更进一步,您甚至可以将具有特定于文化状态的对象序列化到资源文件中。您可以在资源文件中存储的内容没有限制!

最后,我想提及一些在本地化 ASP.NET 页面时需要考虑的注意事项。上面提到的实现步骤是本地化被泛化的那种,因此一个实现(或页面)可以提供任何文化的内​​容。通过使用 `ResoureManager` 和额外的程序集,我们在内存和处理时间方面会产生一些开销。另一方面,我们可以摆脱泛化代码,并保留源文件的副本(每种支持的文化一个)。这种方法实际上被许多网站使用。在这种情况下,唯一的开销将是开发工作,但页面可能会稍微快一点。

结论

到目前为止,我们只看到了开发国际化应用程序的两个方面。我想说,我们刚刚踏上了一段相当长(而且希望是有趣)的旅程。在下一篇文章中,我将介绍其他方面,如日期、时间、数字格式等。在结束之前,我想提一些其他关于国际化的好资源。

© . All rights reserved.