多语言实现详解
附件描述:
MutiLangDemo1.rar为演示项目文件,下载后可直接运行。
MutiLangTool.rar为一个辅助小工具,将会在你选择的目录下为每个aspx页面生成资源文件名并放在创建的App_LocalResources目录中,资源文件并没有将相应的页面的资源(因各种原因生成资源功能已去掉),但也能为你节省修改资源名的时间。
1.1 页面整理和资源生成
为了能快速掌握核心内容,例子尽可能的简单。
首先,用vs 2008建立一个web项目,上面可以放一些简单的控件,如下:
接下来我们生成资源文件,如下:
注意:生成资源文件之前,最好先检查一下你的页面,做好相关的整理,这种生成方式只会为asp.net服务器端控件生成资源文件,即<asp:..></asp>控件,而不会为<input../> <span../>等生成资源文件,所以必须用相应的<asp:Label>,<asp:Button>替换好整理完成之后再生成。
接下来我们看看点击生成资源文件之后vs都为我们做了什么,打开项目视图,发现多了一些文件:
图中,App_LocalResources文件夹是新生成的,而Index.aspx.resx正是Index.aspx页面的资源文件,打开看看:
上图中,选择的PageResource1.Title是每个资源文件都会有的,它就是aspx页面中的<title>Index Page</title>,其他就是页面上的Label和Button等的资源。下面简要介绍一下.net下的资源文件,它其实一个xml文件,打开展示如下:
而微软提供相应的类来操作资源文件,引用命名空间using System.Resources;即可使用,
有了它你就可以批量动态生成资源文件了,毕竟简单机械重复的劳动没人喜欢。
资源文件是生成了,但是页面是怎么引用这些资源的呢,多语言和这些资源有哪些关系呢,现在打开页面你就知道了。
相信你已经看出变化的地方了。现修改资源文件为:
运行之后首页显示为:
至此,页面上需要显示的文字都已经放在了资源文件里面了,多语言的实现也就借助资源文件实现的,比如需要中英文的网页,就需要为每个页面创建至少两份资源文件,一份中文资源文件,一份英文资源文件,如下:
把先前生成的资源文件拷贝两份,请注意命名规则,如果命名不规范,你的资源文件将不起作用,如果你不是很了解,可以google或者百度一下,还有一个简单方法,打开IE,选择工具-》Internet选项-》常规-》语言-》添加;你就可以看到每种语言的代码,如美国英语就是en-us,相应的资源文件命名如上图中的Index.aspx.en-us.resx。打开英文资源文件,把相应的Value列的文字都改成英语。
那么怎么实现多语言之间的转换呢,请继续下看。
1.2.后台实现
后台实现的关键地方在于重写InitializeCulture()函数,这个函数在程序装载页面之前就会执行。
将下面代码复制到index.asp.cs中
protected override void InitializeCulture()
{
string selectedLanguage =
string.Empty;
if (Session[
"language_session"] !=
null && Convert.ToString(Session[
"language_session"]) !=
string.Empty)
{
selectedLanguage = Convert.ToString(Session[
"language_session"]);
}
else {
selectedLanguage = Request.Headers[
"accept-language"].Split(
",".ToCharArray())[0].ToString().ToLower();
Session[
"language_session"] = selectedLanguage;
}
setCulture(selectedLanguage);
}
protected void lbtnLanguage_Click1(
object sender, EventArgs e)
{
String selectedLanguage =
"en-us";
if (
null != Session[
"language_session"])
{
if (
"en-us" == Session[
"language_session"].ToString())
{
Session[
"language_session"] =
"zh-cn";
selectedLanguage =
"zh-cn";
}
else if (
"zh-cn" == Session[
"language_session"].ToString())
{
Session[
"language_session"] =
"en-us";
selectedLanguage =
"en-us";
}
}
else {
Session[
"language_session"] =
"en-us";
}
}
private void setCulture(
string selectedLanguage)
{
UICulture = selectedLanguage;
Culture = selectedLanguage;
System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(selectedLanguage);
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(selectedLanguage);
}
执行效果如下:
点击English后效果为:
实际项目中,上述代码一般放在一个所有页面的父类中例如BasePage.cs中,BasePage必须继承于System.Web.UI.Page,并实现上面多语言的功能,其它页面继承BasePage就能实现多语言了。
1.3. 备注
除了上述需要实现多语言的页面之外,还有其他弹出消息,或者控件如日期控件也需要实现多语言,实现方法也非常简单。Javascript中主要需要实现双语的如alert语句中的类容,可以把变量做成资源文件,然后根据用户选择动态引用相应的文件,也可以把全部的Javascript做出N个版本。每个版本代表一种语言版本,各有利弊,可以根据实际情况选择合适的方法。
通常在你实现多语言的过程中,发现经常出现几个页面需要显示的文字其实是一模一样的,但是你却必须在每个页面都得做重复的工作,这时候你就需要把它们整理到App_GlobalResources文件夹下了,
此时引用的方式为表达式方式 如:<asp:Label id="lblWelcome" runat="server" Text="<%$ Resources:Test,lblWelcome%>"></asp:Label> 其中 Test为资源文件去掉后缀resx后的名字,lblWelcome为资源Test.resx中一个Name为lblWelcome一行。
这样页面就会显示为“欢迎光临”,如果有100个页面都会用到这个,就把它放在App_GlobalResources中吧,这样更容易维护。引用本地资源的时候也可以使用上述的表达式方式的方法。