ASP.NET MVC 多语言方案

系统 1815 0

前言:

好多年没写文章了,工作很忙,天天加班, 每天都 相信不用多久 就会升职加薪 当上总经理 出任CEO 迎娶白富美,走上人生巅峰,想想还有点小激动~~~~

直到后来发生了邮箱事件,我竟然忘了给邮箱密码赋值,导致 遇到“邮箱不可用。 服务器响应为: 5.7.1 Unable to relay for”的问题,网上一查后, 让Boss去设置 IIS里的SMTP。

结果Boss力证不用设置也可以发,还给我发了N多Demo代码,让我蛋碎一地, 最后那点小激动,就在这小事件上栽没了~~~

好了,不多扯了,回正文吧~~~


引子:

关于系统的多语言,我在之前的文章都写过不少,包括秋色园QBlog的开源博客里,也有相应的实现方案,不过随着项目环境的不同,往往实现的方案也不尽相同。

今天就来扯扯,ASP.NET MVC下的方案。


1:数据的多语言:

在QBlog里,数据的多语言,我是分成两种方案一起处理:

A:多条数据,文章数据,用一个语言字段来标识该条数据为何种语言。

B:对于其它数据,标题,公告等,用一个[#LangSplit]标识来分隔前后两种语言。

不过现在的方案有点不同,看如下图:

ASP.NET MVC 多语言方案

看到大量的Xml字段了吧,这就是上一个项目继承而来的精华,在项目里动不了事实存在。

关于表名和字段命名方式,走的是国际范,大伙不要学。

针对Xml,需要有一小套处理方案:

数据库以Xml字段存档多语言,格式为:
< ML V ="1.0" >
< M L ="zh-cn" > 中文 </ M >
< M L ="en" > English </ M >
< M L =".." > 其它语言 </ M >
</ ML >

然后针对这种存档,需要有相应的处理:

SQL:查询语法为:

取值:字段名.value('(/ML/M[@L="zh-cn"])[1]','nvarchar(max)')
取节点:字段名.query('/ML/M[@L="en"]')
判断:字段名.exists('/ML/M[@L="zh-cn"]')
排序:用取值后的字段名进行排序


处理流程大体如下:

ASP.NET MVC 多语言方案

2:UI多语言

2.1:MVC View的多语言流程:

ASP.NET MVC 多语言方案

经过对MVC的源码调试,发现在Control基类(自己定义)统一处理即可。

Demo代码:

protected override void OnResultExecuted(ResultExecutedContextfilterContext)
{
if (filterContext.Result is ViewResult)
{
string html=RenderViewToString( this ,((ViewResult)filterContext.Result).View);
html=LanguageMgr.Replace(html, " zh " );
Response.Clear();
Response.Write(html);
}
}
protected static string RenderViewToString(Controllercontroller,IViewview)
{
// IViewview=ViewEngines.Engines.FindView(controller.ControllerContext,viewName,masterName).View;
using (System.IO.StringWriterwriter= new System.IO.StringWriter())
{
ViewContextviewContext= new ViewContext(controller.ControllerContext,view,controller.ViewData,controller.TempData,writer);
viewContext.View.Render(viewContext,writer);
return writer.ToString();
}
}

一开始的想法是处理完后写回去,后来调试了半天源码发现找不到写回去的,灵光一闪,发现数据在Response.OutPut流里,直接清空,输出新的Html即可。

2.2:JS脚本的多语言流程:

ASP.NET MVC 多语言方案

具体的实现,看下面的语法定义。


3: UI多语言的语法方案

界面标签定义:[#对象名称-字段名#],标签内不允许带有空格。


或者直接:[#字段名#](由Controller自动取得对象名称处理)
例如:[#UserID#] 或者[#Login-UserID#]
中文时将被替换成:登陆名,英文就是Login了。

配套的Demo实现:

public class LanguageMgr
{
/// <summary>
/// 替换多语言。
/// </summary>
/// <paramname="html"></param>
/// <paramname="lang"></param>
/// <returns></returns>
public static string Replace( string html, string lang)
{
MatchCollectionmatchs=Regex.Matches(html, @" \[#([\S\s]*?)#\] " ,RegexOptions.Compiled|RegexOptions.IgnoreCase);
if (matchs!= null &&matchs.Count> 0 )
{
List< string >keys= new List< string >(matchs.Count); // 记录已匹配过的

Dictionary< string , string >dic=GetLanguageDic(lang);
foreach (Matchmatch in matchs)
{
string text=match.Groups[ 0 ].Value;
string key=match.Groups[ 1 ].Value.Trim();
if (!keys.Contains(key))
{
keys.Add(key);
if (dic.ContainsKey(key))
{
html=html.Replace(text,dic[key]);
}
}
}
keys= null ;
matchs= null ;
}
return html;
}
internal static Dictionary< string , string >GetLanguageDic( string lang)
{
Dictionary< string , string >dic= new Dictionary< string , string >();
dic.Add( " aaa " , " 中文 " );
dic.Add( " bbb " , " 英文 " );
return dic;
}

4: JavaScript 多语言定义

对于JavaScript需要在客户端调用的多语言,可以在View中进行如下定义语言json:


< script >
var lang={loginID:”[#LoginID#]”,userName:”[#UserName#]”};
<script>

该View会在Controller端提前会替换成相应语言的文字。

之后的引用调用alert(lang.loginID)即可。

总结:

以上的多语言方案,有特定的项目环境背景,仅供参考,讨论,借鉴,反省,请勿轻易模仿。

谢谢观赏。

ASP.NET MVC 多语言方案


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论