前言:
好多年没写文章了,工做很忙,每天加班, 天天都相信不用多久,就会升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰,想一想还有点小激动~~~~html
直到后来发生了邮箱事件,我居然忘了给邮箱密码赋值,致使遇到“邮箱不可用。 服务器响应为: 5.7.1 Unable to relay for”的问题,网上一查后,让Boss去设置IIS里的SMTP。数据库
结果Boss力证不用设置也能够发,还给我发了N多Demo代码,让我蛋碎一地, 最后那点小激动,就在这小事件上栽没了~~~json
好了,很少扯了,回正文吧~~~服务器
引子:
关于系统的多语言,我在以前的文章都写过很多,包括秋色园QBlog的开源博客里,也有相应的实现方案,不过随着项目环境的不一样,每每实现的方案也不尽相同。ide
今天就来扯扯,ASP.NET MVC下的方案。 this
1:数据的多语言:
在QBlog里,数据的多语言,我是分红两种方案一块儿处理:spa
A:多条数据,文章数据,用一个语言字段来标识该条数据为什么种语言。3d
B:对于其它数据,标题,公告等,用一个[#LangSplit]标识来分隔先后两种语言。调试
不过如今的方案有点不一样,看以下图:code

看到大量的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"]')
排序:用取值后的字段名进行排序
处理流程大致以下:

2:UI多语言
2.1:MVC View的多语言流程:

通过对MVC的源码调试,发如今Control基类(本身定义)统一处理便可。
Demo代码:
protected
override
void OnResultExecuted(ResultExecutedContext filterContext)
{
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(Controller controller, IView view)
{
//
IView view = ViewEngines.Engines.FindView(controller.ControllerContext, viewName, masterName).View;
using (System.IO.StringWriter writer =
new System.IO.StringWriter())
{
ViewContext viewContext =
new ViewContext(controller.ControllerContext, view, controller.ViewData, controller.TempData, writer);
viewContext.View.Render(viewContext, writer);
return writer.ToString();
}
}
一开始的想法是处理完后写回去,后来调试了半天源码发现找不到写回去的,灵光一闪,发现数据在Response.OutPut流里,直接清空,输出新的Html便可。
2.2:JS脚本的多语言流程:

具体的实现,看下面的语法定义。
3:UI多语言的语法方案
界面标签订义:[#对象名称-字段名#],标签内不容许带有空格。
或者直接:[#字段名#](由Controller自动取得对象名称处理)
例如:[#UserID#] 或者[#Login-UserID#]
中文时将被替换成:登录名,英文就是Login了。
配套的Demo实现:
public
class LanguageMgr
{
///
<summary>
///
替换多语言。
///
</summary>
///
<param name="html"></param>
///
<param name="lang"></param>
///
<returns></returns>
public
static
string Replace(
string html,
string lang)
{
MatchCollection matchs = 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 (Match match
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)便可。
总结:
以上的多语言方案,有特定的项目环境背景,仅供参考,讨论,借鉴,检讨,请勿轻易模仿。
谢谢观赏。