在您的 ASP.NET Web 应用程序中允许用户选择用户界面语言






4.84/5 (18投票s)
演示了开发人员如何在其 Web 应用程序中引入语言选择功能。
引言
如果您认为您的 Web 应用程序将供来自不同国家、说不同语言的人使用,您可能需要考虑提供语言选择功能。这是所有国际化应用程序中非常常见的功能,在 .NET 4 Web 应用程序中实现起来相当容易。
这是该文章的改进版(第二版),是在收到会员(尤其是 graffic)的 评论 后完成的。
这样的功能应该由什么组成?
这是最基本的要求列表
- 自动检测用户在其浏览器中设置的语言偏好。
- 用户在您的应用程序中更改用户界面语言的方式。
- 当用户更改语言时,用户正在查看的当前页面不应丢失,用户也不应被重定向到默认页面。
- 所选语言需要在页面视图之间持久存在。我们无疑不应期望用户在他们访问的每个页面上都设置他们偏好的语言。
- 至少,您的 Web 应用程序中的所有标签都应以用户所选语言显示。
实现
自动检测用户在其浏览器中设置的语言偏好
在您的 web.config 文件中,您需要设置以下 globalization 标签,并使用下面显示的值:
<system.web>
<globalization
uiCulture="auto"
culture="auto"
enableClientBasedCulture="true" />
</system.web>
信不信由你,这足以让用户在您的 Web 应用程序中使用他们偏好的语言。然而,并非所有用户都知道如何在浏览器中设置语言偏好,并且通常期望有一种方法来使用诸如图片、链接或下拉选择框之类的东西在您的 Web 应用程序中选择他们偏好的语言。
允许用户在您的 Web 应用程序中选择语言
语言选择模块
首先,您需要在服务器上实现一个语言选择模块。
using System;
using System.Web;
using System.Threading;
/// <summary>
/// Summary description for LanguageModule
/// </summary>
public class LanguageModule:IHttpModule
{
public void Init(HttpApplication context)
{
context.AcquireRequestState += new EventHandler(OnAcquireRequestState);
}
public void Dispose()
{
}
public void OnAcquireRequestState(Object i_object, EventArgs i_eventArgs)
{
HttpApplication l_httpApplication = i_object as HttpApplication;
// check whether the language change parameter has been passed
var l_language =
l_httpApplication.Request.Params[Constants.SESSION_LANGUAGE];
var l_boolLanguageChanged = false;
if (l_language == null)
{
// if language parameter is not sent, then take language from session
l_language = (string)l_httpApplication.Session[Constants.SESSION_LANGUAGE];
}
else
{
// If language parameter is indeed sent, then user wants to change language.
// I will make sure I tag this in order to redirect to.
l_boolLanguageChanged = true;
}
// having the language a thand, let us set it.
var l_culture = new System.Globalization.CultureInfo(l_language);
Thread.CurrentThread.CurrentCulture = l_culture;
Thread.CurrentThread.CurrentUICulture = l_culture;
// save language to session
l_httpApplication.Session[Constants.SESSION_LANGUAGE] = l_language;
// check whether I have redirect
if (l_boolLanguageChanged && l_httpApplication.Request.UrlReferrer != null)
{
l_httpApplication.Response.Redirect(
l_httpApplication.Request.UrlReferrer.AbsolutePath);
}
} // OnAcquireRequestState
//-------------------------
} // class LanguageModule
//------------------------
这里发生了什么?该模块在 AcquireRequestState
上注册一个 EventHandler
,并确保它要么使用通过请求传递的语言参数,要么使用从先前请求中存储在 Session
中的语言。在设置了本地变量 l_language
后,它会创建必要的 CultureInfo
对象,并将其设置为 Thread.CurrentThread.CurrentCulture
和 CurrentUICulture
。然后,它将选择保存在 Session
中,并重定向到用户更改语言时的页面。请注意,重定向仅在用户实际请求更改语言时(通过在其请求中传递语言参数)发生。否则,不会发生重定向。
(*) AcquireRequestState
是请求处理过程中的一个点,在该点我们可以使用 Session 进行处理。
由于您正在创建一个 HTTPModule
,请不要忘记告诉您的 .NET 运行时您希望它在请求处理链中。这可以通过在 web.config 文件中的一个特殊条目来完成。这是演示中的条目(它在 system.web
部分):
<httpModules>
<add name="LanguageSettingModule" type="LanguageModule, App_Code" />
</httpModules>
更改语言的用户界面
这取决于您的选择和品味。按照您喜欢的方式去做。无论如何,您都应该找到一种方法来向服务器发送如下请求:
http://www.mymultilingualsite.com/?language=el
用于选择希腊语。或者
http://www.mymultilingualsite.com/?language=en
用于选择英语,以此类推。在该文章附带的演示代码中,我在我的 Master 页面上添加了一段代码,允许用户选择以下三种语言之一:希腊语、英语、俄语。这是我的 Master ASPX 页面中的代码片段(我将此类代码放在 Master 页面中,以便我的网站的所有页面都可以访问它):
<%@ Master Language="C#" AutoEventWireup="true"
CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:HyperLink ID="hprlnkGreek" runat="server"
NavigateUrl="~/?language=el"/>|
<asp:HyperLink ID="hprlnkEnglish" runat="server"
NavigateUrl="~/?language=en"/>|
<asp:HyperLink ID="hprlnkRussian" runat="server"
NavigateUrl="~/?language=ru"/>
<hr />
<asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
在 Session 中保存用户选择的语言
如您之前在语言选择模块的代码中所见,我们将用户选择的语言存储在 Session 中。这需要一些小的准备。
- 为用于在 Session 中存储语言的键创建一个常量。我已在一个名为
Constants
的特殊类中完成了此操作。这是代码: - 在我的 Global.asax 中,我创建了这个键,并将其设置为当前选择的用户界面文化语言,如下所示:
public class Constants
{
public const string SESSION_LANGUAGE = "language";
}
void Session_Start(object sender, EventArgs e)
{
// Code that runs when a new session is started
Session.Add(Constants.SESSION_LANGUAGE,
System.Globalization.CultureInfo.CurrentUICulture.TwoLetterISOLanguageName);
} // Session_Start
多语言标签
最后,您需要使您的标签支持多语言。这是一个五步过程:
- 在您的项目中创建一个 ASP.NET 文件夹。文件夹类型需要是
App_GlobalResources
。 - 添加一个新的
ResourceFile
项。此文件的名称不应包含任何语言规范。例如,LocalizedResources.resx。此文件将保存您网站默认语言的字符串。在演示中,默认语言是英语。 - 为(除默认语言外)您想要支持的每种语言添加一个新的
ResourceFile
项。每种特定语言的文件名都必须包含语言规范。例如,俄语文件必须命名为 LocalizedResources.ru.resx。您看到 .ru. 了吗?它代表俄语。或者,对于希腊语,文件必须是 LocalizedResources.el.resx。您看到 .el. 了吗? - 这些文件将需要包含您需要多语言支持的所有字符串。默认资源文件将包含您网站默认语言的翻译。其他资源文件将包含相应语言的翻译。
- 然后您需要使用资源字符串,而**不要**在代码中手动编写标签值。例如,请查看 Customers.aspx 文件以及
Firstname
标签是如何构建的:
<asp:Label ID="lblFirstname" runat="server"
Text="<%$ Resources:LocalizedResources, Firstname %>" />
您看到 Text
属性是如何设置的吗?Firstname
是一个本地化字符串,在我演示项目的所有资源文件中都有翻译。很简单,对吧?
然后,这一切都是 .NET 的魔法。标签将根据用户选择的语言显示正确的字符串/翻译。
改善语言选择用户体验的技巧
这是一个开始。您可以从以下几个方面改善语言选择的用户体验:
- 将用户选择的语言保存在 cookie 中。这样,下次用户访问您的 Web 应用程序时,即使他没有在浏览器中设置偏好语言,您也可以将其设置为用户在上一次访问您的网站时选择的语言。
- 或者,您可以将此选择保存在数据库的用户首选项表中。
- 多语言资源以及 .NET 如何管理它们非常强大。您不仅限于多语言字符串。根据所选语言,您可以:
- 显示不同的图片
- 使用不同的图标
- 播放不同的音频文件
- 引用不同的外部文件
结论
我相信我们已经涵盖了 此处 设置的所有功能要求。我希望这篇文章能为您提供一个起点,使您的应用程序能够支持多语言并吸引国际用户。
历史
- 2011 年 5 月 14 日 - 文章第二版发布,使用 HTTPModule 处理语言更改。
- 2011 年 5 月 7 日 - 文章第一版发布。