.Net实现本地化简易教程

实现多语言版本的支持,就是所谓的国际化,也说是本地化。

今天这里将要介绍的是.Net里面实现本地化的介绍。网上有很多文章介绍怎么实现本地化,但是大多不适合初学者去学习,因为初学者需要更为详细的介绍以及图表作为说明。

所以本着互相学习的想法,我也写一下自己最近学习的心得体会。

首先,这里面需要介绍一些知识。当然,你可以从文中选择哪些是你需要的内容来进行阅读。

这里面我们要说明的是全局资源文件,全局资源文件是存放在App_GlobalResources的文件夹里面。在Web Form里面创建这个文件夹很简单,在“解决方案的资源管理器”中右键项目(WebSite或者是Application),选择Add->Add ASP.NET Folder->App_GlobalResources(如下图所示)。应用程序中只能有一个这样的文件夹,且处于应用程序根目录下,当然里面的资源文件就不是惟一的。

 

未命名

 

还有另一种是局部资源文件,它跟全局资源文件类似,不一样的就是存放的文件夹名字不一样,局部资源文件夹是App_LocalResources。在应用程序里面,这样的文件夹数量没有作限制,而且也不限定它的位置。

第一点:实现Asp.net服务端控件本地化。

实现Asp.net服务端控件的本地化,非常简单。一旦想给服务端的控件添加本地化信息,那么你就可以按如下的步聚来实现你的本地化操作。进入到设计视窗,然后鼠标点击其中的一个服务端控件,然后选中菜单上的"Tools->Generate Local Resource”(如下图)。然后VS2010就会为你创建此页面的资源文件。然后在应用程序里面,你会发现多了一个文件夹App_LocalResources,并且里面多了一个以刚才编辑页面命名的资源文件。被编辑的页面是Login.aspx页面,这时,你会在Login.aspx里面看到VS2010生成了一个新的目录App_LocalResources,并且里面多了一个文件Login.aspx.resx。注意,这里的本地化文件的命名是固定的,不能被改变,一个本地化文件对应一个页面文件。

 

1

2

双击资源文件Login.aspx.resx,并给其中的Value框输入你需要的Value值。资源文件里面的Name值是Login.aspx服务端控件里面的属性。这里需要讲一下,资源文件并不只限于文本格式,其实还包括很多种格式的资源文件。下图中在Login.aspx.resx底下有“Strings”下拉框(向下的三角形),点击即可选择需要添加的资源文件,并点击“Add Resource”下拉框选择添加。

3

添加完资源文件的话,服务端控件的本地化就实现完了,这时候你Ctrl+F5运行后,可以看到你登录页(Login.aspx)的内容就是你填写的资源文件的内容。这里面资源文件的内容(上图写Name对应的Value值)我就不贴Login.aspx.resx图了,我贴个结果吧。Login.aspx.resx是工具自动生成的文件,所以你不需要的列,你可以对其进行删除或者是修改操作。

4

其实这里还有一个图需要说明的,不知道你有没有看到每个服务端控件的代码里面,多了一个属性。类似meta:resourcekey="RegisterHyperLinkResource1"。

5

这里面需要说明的是,它只对服务端控件起作用,不是服务端控件的文本,如果也想用资源文件的方式来做的话。下文会使用另一个控件来做(<asp:Localize>)。回过头来说,我们是实现对多语言的支持,那么资源文件当然是需要多个的,比如再创建一个叫Login.aspx.en.resx的资源文件在App_LocalResources里面。

6

改变浏览器阅读网站首选项的语言,再刷新浏览器里面Login.aspx页面,你就会发现里面使用的语言变成是英语,而不是刚才的中文。改变浏览器阅读网站语言的设置如下:以IE做说明,IE菜单:工具->Internet选项->语言->添加->选择英语。这里之后需要注意的是:英文需要排在第一位,不然不会起作用

未命名7

 

上面介绍了怎么实现Asp.Net里面服务端控件的本地化,那普通的文本呢?其实普通的文本也可以支持到。但是感觉普通的文件其实跟用个Label的方式来做有什么不同了?

许就是Label会自动生成更多的Name名(在资源文件里面),省去我们删除的工作吧。所以人家微软给你另一种支持了,如果你觉得可以用,那就用吧。拿上文登录页Login.aspx页面的代码来说吧:

    <p>Please enter your username and password.           

          <asp:HyperLink ID="RegisterHyperLink" runat="server" EnableViewState="False"
             meta:resourcekey="RegisterHyperLinkResource1"> Register</asp:HyperLink>           

          if you don't have an account.
   </p>

这里面我们可以用<asp:Localize>服务端控件,这个控件位于工具箱里的标准类别里面。加入了Localize后代码如下所示:

    <p>
         <asp:Localize ID="Header" runat="server"> Please enter your username and password.</asp:Localize>           

        <asp:HyperLink ID="RegisterHyperLink" runat="server" EnableViewState="False"
              meta:resourcekey="RegisterHyperLinkResource1">Register</asp:HyperLink>           

        <asp:Localize ID="Footer" runat="server"> if you don't have an account.</asp:Localize>
    </p>
 

其实到了这一步之后,又需要用到我们在上面提到的一个属性meta:resourcekey="HeaderResource1”,然后在资源文件里面写需要显示的内容。
这里面如果你不
知道资件里面的Name值是什么的话,其实也可以跟开始那样,在设计视窗里面点击里面的服务端控件,然后“Tools->Generate Local Resource”。这后之后它就会变成如下代码:

<p> <asp:Localize ID="Head" runat="server" meta:resourcekey="HeadResource1"
              Text="Please enter your username and password."></asp:Localize>

          <asp:HyperLink ID="RegisterHyperLink" runat="server" EnableViewState="False"
              meta:resourcekey="RegisterHyperLinkResource1"Text="Register">
         </asp:HyperLink>           

         <asp:Localize ID="Footer" runat="server" meta:resourcekey="FooterResource1"  

              Text=" if you don't have an account."></asp:Localize>
   </p>

然后在资源文件里面,你也能看到相应的变化,不过它只改变默认的一个资源文件,其它不同语言的资源文件它并不会同步改变
下图我还有一个地方想说明一下,那就是底下的Access Modifier下拉框,里面三种访问修辞符。Public是公共访问的,Internal是程序里面访问的,No code generation应该就是这种不需要使用代码来访问的。

8
 

上面提到的都还只是局部资源文件里面的内容,下面我们要介绍下全局资源文件夹里面的资源文件是怎么使用的。这里介绍的是用代码的方式来实现本地化。说到全局资源文件,那就是放App_GlobalResources文件里面的资源文件。添加此文件夹的方法,我想大家都知道了,本文开始的部分就有 介绍了,跟局部资源文件夹的方法一样。接着我们就来新建我们的全局资源文件GlobalResource.resx。

9
10

这里面有必要看一下GlobalResource.resx的后置文件----GlobalResource.Designer.cs。

11
12

在全局资源文件里面加了Name为Test,Value为测试的内容保存之后,你会发现在它的后置代码(GlobalResource.Designer.cs)文件里面增加了如下的内容:

 internal static string Test {
             get {

                 return ResourceManager.GetString("Test", resourceCulture);

             }
       }

这个代码应该不难懂吧,它就是用Test属性来取文本值。这里需要注意的是它是internal的访问修辞符,和一个静态属性。所以你在代码里面加入了这个类的命明空间之后,就可以通过类的属性方式来获取资源文件里面文本的内容,当然其它资源类型也是一样的获取方式,只不是属性的返回类型不一样而已。

(1)在cs代码里面直接获取:string content = Resources.GlobalResource.Test
(2)Resource表达式:
<asp:Localize ID="Head" runat="server"  Text="<%$ Resources:GlobalResource, Test %>"></asp:Localize>
这里面Resources是命明空间GlobalResource是类名Test是类里面的属性,通过它们来取到资源文件的值。
(3)使用GetGlobalResourceObject方法:
string content = GetGlobalResourceObject("GlobalResource", "Test").ToString();
这里GetGlobalResourceObject方法返回的是一个Object
对比一下,局部的作法:
(1)Resource表达式:<asp:Localize ID="Head" runat="server" 
Text=" <%$ Resources:LoginButtonResource1.Text %> "></asp:Localize>
这是局部资源文件的绑定方法,在局部资源文件里面,没有对应的后置文件,就是没有.cs文件,直接用固定的方式来取值。Resources是
默认的命明空间名,这里不像全局可以改变(至少我是没有发现),冒号后面的就是局部资源文件里面的Name值。
(2)meta:resourceKey,就是服务端控件本地化的实现
(3)GetLocalResourceObject方法,跟GetGlobalResourceObject类似。
最后,作为收尾的介绍。我们来讲讲实现动态本地化的方式
这里面我们还是以登录页(Login.aspx)为例来作说明,在页面中增加语言的选择下拉框,让用户可以选择想要的语言来实现本地化。
Login.aspx.cs代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;
using System.Globalization;

namespace ResourceWebForm.Account {

     public partial class Login : System.Web.UI.Page     {

          protected void Page_Load(object sender, EventArgs e)         {

          } 

          //枚举语言类型 
          enum Language
          {
              English,
             Chinese
         }

         protected override void InitializeCulture()  {

            //获取select下拉框里面的值
          string language = Request.Form["ddlLanguageName"];
          string languageId = ""; 

            if (!string.IsNullOrEmpty(language)) {
               try {
                 //把字符串转为枚举类型
                 Language enumLanguage=(Language)System.Enum.Parse(typeo(Language),language);

                   switch(enumLanguage)  {
                       case Language.Chinese:
                           languageId = "zh-CN";
                           break;
                       default:
                           languageId = "en-US";
                           break;
                   }

               }catch(Exception ex){

                   languageId = "en-US";

               }

               Thread.CurrentThread.CurrentCulture=CultureInfo.CreateSpecificCulture(languageId);
             Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageId);

            }
              base.InitializeCulture();
         }
     }
}

在Login.aspx页面里面相比之前的内容只是加了一个下拉框跟一个按钮来提交语言的改变(在下图底下的代码)。这里通过重写父类的方法InitializeCulture()来达到本地化的效果。此方法用来初始化页面的Culture和UICulture的信息。在 ASP.NET Web网页当中,您可以设定这两个文化特征值,即 CultureUICulture 属性。Culture 值判定与文化特性相关功能的結果 (例如,日期、数字和货币格式等)。
UICulture 值判定為网页载入的资源。如果想了解更多,可以参照此链接Page.InitializeCulture方法。关于上面代码的languageId,你如果不知道还有语言的简写的话,可以用上面的方法,在浏览器里面:IE菜单:工具->Internet选项->语言->添加,这样你就知道每种语言的简写是什么了。

18
<p>
         <select id="ddlLanguage" name="ddlLanguageName">
             <option value="English" selected="selected">English</option>
             <option value="Chinese">Chinese</option>
         </select>           <asp:Button ID="ChangeBtn" runat="server" Text="Change Language" />
   </p> 

这里面主要改变的是App_LocalResources局部资源文件夹里面的文件内容(Login.aspx.resx和Login.aspx.zh.resx),全局资源文件的作法也类似局部资源文件的作法
12

13
结尾:本文到此就基本简单地介绍了Resource资源文件的使用,如果你们觉得有什么问题的话,欢迎指出,毕竟我也是刚开始学习没多久,
在你们的教导下,我相信自己能学得更好。至少思维的碰撞能让我们理解得更加透彻吧。如果你觉得本文还揍合过去,想转载的话,请务必加上此标注
最后祝大家学得快乐:)
posted @ 2011-10-17 13:07  csdbfans  阅读(4194)  评论(19编辑  收藏  举报