人无信不立/2008-04-26 22:30

ASP.NET中多国语言的实现

现在的程序越来越要考虑国际化了,对于网站的开发也经常要考虑国际化的问题。
常见的国际化的需求主要就是两个方面:
1、不同的国家页面布局不同
2、不同的国家要显示当国的文字
在ASP.NET2.0中实现这两种需求的方法很多,我今天就总结其中一种方法的具体实现。

对应需求1我们可以使用母版页来实现,对于需求2可以使用资源文件的方式来实现。
在母版页中定义好页面布局和各种语言的转换链接,每种语言定义一个母版页,比如中文就叫Chinese.master,英文就叫English.master
Chinese.master 示例
其他语言的母版页也是类似

然后可以在每个aspx的Page_PreInit事件中调用共通的方法来进行语言的动态转换
    protected void Page_PreInit(object sender, EventArgs e)
    
{
        Util.ChangeLanguage(Request, 
this);
    }

        public static void ChangeLanguage(HttpRequest Request, Page page)
        
{
            
string strLanguage = Request.QueryString.Get("language");
            
if (strLanguage != null)
            
{
                page.Session[Util.SESSION_LANGUAGE] 
= strLanguage;
            }

            strLanguage 
= page.Session[Util.SESSION_LANGUAGE] as string;
            
string strMasterPage = "~/Front/MasterPage/" + strLanguage + ".master";
            page.MasterPageFile = strMasterPage;


            
string strUICulture = "";
            
switch (strLanguage)
            
{
                
case "English":
                    strUICulture 
= "en-us";
                    
break;
                
case "Japanese":
                    strUICulture 
= "ja";
                    
break;
            }

            page.UICulture = strUICulture;

        }
主要就是在ChangeLanguage方法中首先改变页面的母版页,然后再改变页面的区域

然后可以在Global.asax全局的Session_Start事件中设置初始语言:
    void Session_Start(object sender, EventArgs e) 
    
{
        Session[Util.SESSION_LANGUAGE] 
= "Chinese";
    }
我这个例子中是直接设置初始为中文语言,当然也可以根据客户端的环境来动态设置的:
    void Session_Start(object sender, EventArgs e) 
    
{
        
switch (Session.LCID)
        
{
            
case 0x0009:
                Session[Util.SESSION_LANGUAGE] 
= "English";
                
break;
            
case 0x0011:
                Session[Util.SESSION_LANGUAGE] 
= "Japanese";
                
break;
            
default:
                Session[Util.SESSION_LANGUAGE] 
= "Chinese";
                
break;
        }

        
//Session[Util.SESSION_LANGUAGE] = "Chinese";
    }

通过以上步骤我们已经可以动态改变页面布局(母版页)和页面的区域了。

下面新建三个全局的资源文件:Resource.resx,Resource.en-us.resx,Resource.ja.resx
在三个资源文件中都加入TestString这个键值,value值写上不同的语言
然后我们就可以在自己的Page页面中使用这个资源文件了:
<%@ Page Language="C#" MasterPageFile="~/Front/MasterPage/Chinese.master" AutoEventWireup="true"
CodeFile
="index.aspx.cs" Inherits="index" 
%>
<asp:Content ID="Content1" ContentPlaceHolderID="Top" Runat="Server">
    
<asp:Label ID="Label1" runat="server" Text="<%$ Resources:Resource,TestString %>" Width="76px">
</
asp:Label><br />
    
<br />
</asp:Content>

也就是说以后出现文字或和区域有关的图片的时候都要在不同的资源文件中定义好,然后在页面中使用<%$ Resources:Resource,TestString %>的方式取值

虽然麻烦了一点,但还是比较方便的,有此需求的可以参考一下,如果有更好的实现方案也欢迎讨论。


posted @ 2008-03-13 17:24 永春 阅读(3052) 评论(24)  编辑 收藏 所属分类: .Net

  回复  引用  查看    
#1楼 2008-03-13 17:38 | 重典      
感觉还是麻烦了些,不知道有没有更好的方法##我是直接将对象序列化了2套,一中一英,然后调用
  回复  引用    
#2楼 2008-03-13 17:50 | designbeauty [未注册用户]
界面的不同最好用css来控制
  回复  引用  查看    
#3楼 2008-03-13 17:50 | Clark Zheng      
http://www.cnblogs.com/reonlyrun/archive/2007/03/14/ASP_Net_Localization_Study.html

不知道这样算不算个方案
  回复  引用  查看    
#4楼 [楼主]2008-03-13 18:12 | 永春      
@Clark Zheng
不错,很详细
和我的方案有点像,都是使用资源文件的方式
  回复  引用  查看    
#5楼 [楼主]2008-03-13 18:15 | 永春      
@重典
序列化也能实现多国语言?没试过
  回复  引用  查看    
#6楼 [楼主]2008-03-13 18:16 | 永春      
@designbeauty
css也是可以的,不过还是要在每个页面动态切换css的
  回复  引用  查看    
#7楼 2008-03-13 18:22 | 重典      
@永春

就是我的语言其实是保存在一个模型对象中的,将其序列化成N个语言版本的XML

这样,换语言只要换不要的Xml反序列化就好了

其实与使用资源的原理是差不多的

  回复  引用  查看    
#8楼 [楼主]2008-03-13 18:26 | 永春      
@重典
哦,明白了
  回复  引用    
#9楼 2008-03-13 19:02 | Wuvist [未注册用户]
我折腾的基于Gettext的asp.net网站多语言解决方案:
http://www.cnblogs.com/wuvist/archive/2007/03/31/Gettext_On_ASP_DotNet.html
  回复  引用  查看    
#10楼 2008-03-13 20:34 | showfan      
建议用Cookie存储UICulture,

在Global.asax中,用Application_AcquireRequestState代替Session_Start:

void Application_AcquireRequestState(Object sender, EventArgs e)
{
HttpCookie cookie = this.Request.Cookies["UserCulture"];
if (cookie != null)
{
string s = cookie.Value;
System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo(s);
System.Threading.Thread.CurrentThread.CurrentUICulture = culture;
System.Threading.Thread.CurrentThread.CurrentCulture = culture;
}
}

  回复  引用  查看    
#11楼 2008-03-13 22:25 | 张子阳.      

@showfan

语言是根据浏览器如何设置的去分别进行显示的吧,为什么要设置Cookie?让用户自己选择语言么?我的做法是读取Threading.Thread.CurrentThread.CurrentUICulture 判断用户使用的是什么语言,然后根据这个值去对显示处理。

处理有两种方式,对于零散的页面显示,直接用App_GlobalResources。对于需要读数据库的大量数据(数据库存了两个版本的),只要根据CultureInfo去使用不同的SQL语句就可以了。


  回复  引用  查看    
#12楼 [楼主]2008-03-14 08:45 | 永春      
@showfan
cookie是可以比session保存的时间长一点,怕客户端不支持cookie的

Application_AcquireRequestState不错,可以统一处理
  回复  引用  查看    
#13楼 [楼主]2008-03-14 08:46 | 永春      
@张子阳.
我们的需求是可以让用户自由选择语言的
  回复  引用    
#14楼 2008-03-14 09:27 | NetCase [未注册用户]
@showfan
Threading.Thread.CurrentThread.CurrentUICulture 去到是服务器的语言不是客户端的。你的方法不行。
  回复  引用  查看    
#15楼 2008-03-14 09:31 | 丁一      
@张子阳.
@永春.

我也建议使用 cookie 或 profile
如果某个中国人出差在国外,
使用国外的办公电脑上网(比如英文操作系统),
但他可能希望通过一次设置后,
以后每次打开网页时看到的是中文的..

  回复  引用  查看    
#16楼 2008-03-14 09:46 | Clark Zheng      
@丁一
兄弟呀,只有存在profile里才有可能在任何地点,任何地方打开都是以前自己设置的语言习惯吧,cookie怎么实现?
  回复  引用  查看    
#17楼 [楼主]2008-03-14 09:56 | 永春      
@Clark Zheng
丁一的意思应该是 用cookie后,每次换一台电脑只要设置一次就可以了,不要每天都设置的
  回复  引用  查看    
#18楼 2008-03-14 16:14 | Azuresong      
可以先判断cookie,如果cookie为空就取HTTP HEADER里的用户浏览器默认语言。
  回复  引用    
#19楼 2008-03-16 19:03 | 海宏软件 [未注册用户]
我的办法:
建立几个目录:zh-cn en-gb等等,首先做中文的,然后把ASPX文件全部复制到en-gb目录,把里边的第一行<% %>之间的zh-cn改成en-gb,然后翻译汉字,代码处理中检查culture处理。

  回复  引用  查看    
#20楼 [楼主]2008-03-17 12:53 | 永春      
@海宏软件
你的方法也可以
不过如果有很多的国家的话就要拷贝很多个aspx页面了,而且改动起来比较麻烦的
  回复  引用    
#21楼 2008-07-02 10:31 | 朱建清 [未注册用户]
楼主您测试过这个吗?

<%$ Resources:Resource,TestString %>
这里已经说明了使有Resource里的TestString. 所以应该是无法自动去根据UICulture来得到相应的Resources里的TestString的吧.
  回复  引用  查看    
#22楼 [楼主]2008-07-02 18:48 | 永春      
@朱建清
这个是我自己写的,运行通过的:)

它会根据UICulture取得不同的资源文件中的值得,你可以试试

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-03-13 17:27 编辑过


相关链接:

历史上的今天:
2007-03-13 随笔20070313