项目中用到多语言的时候最先想到的就是资源文件了,但是这个在开发的时候实在是不方便(反正我是这么觉得的)。
在写代码的同时还要去建资源文件,还要在资源文件中填入内容,当有的翻译不合理修改也是个麻烦事,这个太耗时间。
数据库和XML其它也差不多,主要是在开发阶段还要顾及语言的存放。
我的实现方式:提供一种简单的方式,让程序自动记录页面文本内容,并写入资源文件,XML或数据库中,项目发布的时候只要对程序记录的内容进行翻译即可
以数据库为例
比如页面上的Button: <asp:Button runat="server" ID="Button1" Text=“提交”/>
中文时显示“提交”,如果切换英文则显示成 Submit,
在页面运行时由程序自动将 页面名,控件ID(Button1),文件(“提交”)等信息写入到数据库中。
当项目发布时将数据库中的中文内容翻译成目标语言导入进数据库就可以了。如果要生成资源文件或XML也可以写一段代码将数据库里面的内容自动生成资源文件或XML
Asp.net中调用资源文件是这样写的:
<%$ Resources:LocalizedText,text1%>
我的方式:
1、<%$ Lang:文本%>针对设置了ID的服务器控件
2、<%$ Lang:ID,文本%>针对未设置ID的服务器控件
1、 首先创建一个空的WEB项目
2、 添加类LanguageExpression继承自ExpressionBuilder
内容如下,注释写得很详细了
[ExpressionPrefix("Lang")]
[ExpressionEditor("LangEditor")]
publicclassLanguageExpression : ExpressionBuilder
{
///<summary>
///切换多语言
///参数在GetCodeExpression中的数据中
///</summary>
///<param name="expression"></param>
///<param name="target"></param>
///<param name="entry"></param>
///<param name="ControlID"></param>
///<returns></returns>
publicstaticobjectGetEvalData(stringexpression,Type target,string entry,stringControlID)
{
// ControlID: ID,控件的ID,每个页面唯一就行了。如果是服务器控件程序会获取其ID
// expression:要显示的文本
stringid = ControlID;
string text =expression;
//如果未指定ID
if(ControlID ==null)
{
id = expression.Split(',')[0];
text = expression.Split(',')[1];
}
returnHtmlLang.Lang(id, text);
}
publicoverrideobjectEvaluateExpression(object target,BoundPropertyEntry entry,objectparsedData,ExpressionBuilderContextcontext)
{
// string id = entry.ControlID;
// string text = entry.Expression;
returnGetEvalData(entry.Expression, target.GetType(), entry.Name, entry.ControlID);
}
//重写GetCodeExpression初始化时执行
publicoverrideCodeExpressionGetCodeExpression(BoundPropertyEntryentry,object parsedData,ExpressionBuilderContext context)
{
Typetype1 = entry.DeclaringType;
PropertyDescriptordescriptor1 =TypeDescriptor.GetProperties(type1)[entry.PropertyInfo.Name];
CodeExpression[]expressionArray1 =newCodeExpression[4];
expressionArray1[0] =newCodePrimitiveExpression(entry.Expression);
expressionArray1[1] =newCodeTypeOfExpression(type1);
expressionArray1[2] =newCodePrimitiveExpression(entry.Name);
expressionArray1[3] =newCodePrimitiveExpression(entry.ControlID);
returnnewCodeCastExpression(descriptor1.PropertyType,newCodeMethodInvokeExpression(new
CodeTypeReferenceExpression(base.GetType()),"GetEvalData",expressionArray1));
}
publicoverrideboolSupportsEvaluate
{
get{returntrue;}
}
3、 配置WEBCONFIG文件
添加如下节点
<expressionBuilders>
<addexpressionPrefix="Lang"type="WebApplication1.Code.LanguageExpression"/>
</expressionBuilders>
expressionPrefix: 自己定义就可以了
type:及刚才定义的LanguageExpression类
4、 添加类,用于处理语言配置信息
这个很简单,就不多描述了,代码:
publicclassSysConfig
{
publicenumLanguageType
{
zh_cn = 0,
en_us = 1
}
///<summary>
///中英文标识
/// 中文:zh-cn
/// 英文:en-us
///</summary>
publicstaticLanguageTypeUserLanguage
{
get
{
if(HttpContext.Current.Request.Cookies["Language"] == null)
{
UserLanguage =LanguageType.zh_cn;
}
return(LanguageType)Enum.Parse(typeof(LanguageType),HttpContext.Current.Request.Cookies["Language"].Value);
}
set
{
HttpCookieUserCookie =newHttpCookie("Language",value.ToString());
HttpContext.Current.Response.Cookies.Add(UserCookie);
}
}
}
5、再添加一个类处理你自己要做的事情,比如读写XML,数据库,资源文件等,
如下:
publicclassHtmlLang
{
publicstaticstringLang(string id, stringtext)
{
//得到页面,唯一ID及文本,然后根据SysConfig.UserLanguage来判断显示中文还是英文
stringPageName =HttpContext.Current.Request.Path.Split('/').Last();
switch(SysConfig.UserLanguage)
{
caseSysConfig.LanguageType.zh_cn://中文
text ="中文";
//添加你自己的操作,读写数据库,XML,资源文件等信息,这个时候就可以把页面上的文本内容写到数据库或XML等文件中,当发布项目时,注释掉写入记录的代码,只保留读取多语言的代码即可
//项目发布时把写入数据库的代码注释掉,只保留读取其它版本语言的代码就行了(如果你将数据库中的内容生成了资源文件,那么在发布的时候将代码改成读取资源文件)。
break;
caseSysConfig.LanguageType.en_us://英文
text ="English";
添加你自己的操作
break;
}
returntext;
}
}
最后就是调用了
新建一个页面,在页面中写如下的测试代码
<%= WebApplication1.Code.HtmlLang.Lang("text1","中文")%>
<label><%= WebApplication1.Code.HtmlLang.Lang("text2","中文")%></label>
<asp:Buttonrunat="server"ID="Button1"Text="<%$Lang:中文%>"
OnClick="Button1_Click"></asp:Button>
后台CS文件中,按扭点击事件
protectedvoidButton1_Click(object sender,EventArgs e)
{
Code.SysConfig.UserLanguage= Code.SysConfig.UserLanguage == Code.SysConfig.LanguageType.zh_cn? Code.SysConfig.LanguageType.en_us: Code.SysConfig.LanguageType.zh_cn;
Response.Redirect(Request.Path);
}
没怎么排版,有点乱,项目结构如下: