前言:
好多年沒(méi)寫文章了,工作很忙,天天加班, 每天都 相信不用多久 , 就會(huì)升職加薪 , 當(dāng)上總經(jīng)理 , 出任CEO , 迎娶白富美,走上人生巔峰,想想還有點(diǎn)小激動(dòng)~~~~
直到后來(lái)發(fā)生了郵箱事件,我竟然忘了給郵箱密碼賦值,導(dǎo)致 遇到“郵箱不可用。 服務(wù)器響應(yīng)為: 5.7.1 Unable to relay for”的問(wèn)題,網(wǎng)上一查后, 讓Boss去設(shè)置 IIS里的SMTP。
結(jié)果Boss力證不用設(shè)置也可以發(fā),還給我發(fā)了N多Demo代碼,讓我蛋碎一地, 最后那點(diǎn)小激動(dòng),就在這小事件上栽沒(méi)了~~~
好了,不多扯了,回正文吧~~~
引子:
關(guān)于系統(tǒng)的多語(yǔ)言,我在之前的文章都寫過(guò)不少,包括秋色園QBlog的開源博客里,也有相應(yīng)的實(shí)現(xiàn)方案,不過(guò)隨著項(xiàng)目環(huán)境的不同,往往實(shí)現(xiàn)的方案也不盡相同。
今天就來(lái)扯扯,ASP.NET MVC下的方案。
1:數(shù)據(jù)的多語(yǔ)言:
在QBlog里,數(shù)據(jù)的多語(yǔ)言,我是分成兩種方案一起處理:
A:多條數(shù)據(jù),文章數(shù)據(jù),用一個(gè)語(yǔ)言字段來(lái)標(biāo)識(shí)該條數(shù)據(jù)為何種語(yǔ)言。
B:對(duì)于其它數(shù)據(jù),標(biāo)題,公告等,用一個(gè)[#LangSplit]標(biāo)識(shí)來(lái)分隔前后兩種語(yǔ)言。
不過(guò)現(xiàn)在的方案有點(diǎn)不同,看如下圖:
看到大量的Xml字段了吧,這就是上一個(gè)項(xiàng)目繼承而來(lái)的精華,在項(xiàng)目里動(dòng)不了事實(shí)存在。
關(guān)于表名和字段命名方式,走的是國(guó)際范,大伙不要學(xué)。
針對(duì)Xml,需要有一小套處理方案:
< ML V ="1.0" >
< M L ="zh-cn" > 中文 </ M >
< M L ="en" > English </ M >
< M L =".." > 其它語(yǔ)言 </ M >
</ ML >
然后針對(duì)這種存檔,需要有相應(yīng)的處理:
取值:字段名.value('(/ML/M[@L="zh-cn"])[1]','nvarchar(max)')
取節(jié)點(diǎn):字段名.query('/ML/M[@L="en"]')
判斷:字段名.exists('/ML/M[@L="zh-cn"]')
排序:用取值后的字段名進(jìn)行排序
處理流程大體如下:
2:UI多語(yǔ)言
2.1:MVC View的多語(yǔ)言流程:
經(jīng)過(guò)對(duì)MVC的源碼調(diào)試,發(fā)現(xiàn)在Control基類(自己定義)統(tǒng)一處理即可。
Demo代碼:
{
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();
}
}
一開始的想法是處理完后寫回去,后來(lái)調(diào)試了半天源碼發(fā)現(xiàn)找不到寫回去的,靈光一閃,發(fā)現(xiàn)數(shù)據(jù)在Response.OutPut流里,直接清空,輸出新的Html即可。
2.2:JS腳本的多語(yǔ)言流程:
具體的實(shí)現(xiàn),看下面的語(yǔ)法定義。
3: UI多語(yǔ)言的語(yǔ)法方案
配套的Demo實(shí)現(xiàn):
{
/// <summary>
/// 替換多語(yǔ)言。
/// </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); // 記錄已匹配過(guò)的
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 多語(yǔ)言定義
var lang={loginID:”[#LoginID#]”,userName:”[#UserName#]”};
<script>
該View會(huì)在Controller端提前會(huì)替換成相應(yīng)語(yǔ)言的文字。
總結(jié):
以上的多語(yǔ)言方案,有特定的項(xiàng)目環(huán)境背景,僅供參考,討論,借鑒,反省,請(qǐng)勿輕易模仿。
謝謝觀賞。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
