好多年沒寫文章了,工作很忙,天天加班, 每天都相信不用多久,就會升職加薪,當上總經理,出任ceo,迎娶白富美,走上人生巅峰,想想還有點小激動~~~~
直到後來發生了郵箱事件,我竟然忘了給郵箱密碼指派,導緻遇到“郵箱不可用。 伺服器響應為: 5.7.1 unable to relay for”的問題,網上一查後,讓boss去設定iis裡的smtp。
結果boss力證不用設定也可以發,還給我發了n多demo代碼,讓我蛋碎一地, 最後那點小激動,就在這小事件上栽沒了~~~
好了,不多扯了,回正文吧~~~
關于系統的多語言,我在之前的文章都寫過不少,包括秋色園qblog的開源部落格裡,也有相應的實作方案,不過随着項目環境的不同,往往實作的方案也不盡相同。
今天就來扯扯,asp.net mvc下的方案。
在qblog裡,資料的多語言,我是分成兩種方案一起處理:
a:多條資料,文章資料,用一個語言字段來辨別該條資料為何種語言。
b:對于其它資料,标題,公告等,用一個[#langsplit]辨別來分隔前後兩種語言。
不過現在的方案有點不同,看如下圖:
看到大量的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"]')
排序:用取值後的字段名進行排序
處理流程大體如下:
經過對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即可。
具體的實作,看下面的文法定義。
界面标簽定義:[#對象名稱-字段名#],标簽内不允許帶有空格。
或者直接:[#字段名#](由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;
}
對于javascript需要在用戶端調用的多語言,可以在view中進行如下定義語言json:
<script>
var lang={loginid:”[#loginid#]”,username:”[#username#]”};
該view會在controller端提前會替換成相應語言的文字。
之後的引用調用alert(lang.loginid)即可。
本文原創發表于部落格園,作者為路過秋天,原文連結:http://www.cnblogs.com/cyq1162/p/3518519.html