• ASP.NET MVC 多语言方案


    前言:

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

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

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

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

    引子:

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

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

    1:数据的多语言:

    在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"]') 
    排序:用取值后的字段名进行排序

    处理流程大体如下:

    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, @"[#([Ss]*?)#]", 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)即可。

    总结: 

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

    谢谢观赏。

     
     
     
    版权声明:本文原创发表于 博客园,作者为 路过秋天 本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
     
     
  • 相关阅读:
    06--添加卡片到游戏
    05--创建卡片类
    04--帮助类ScreenAdapter编写
    03--重新规划程序结构
    02--2048实例搭建滑动框架
    iOS下的 Fixed + Input BUG现象
    textarea高度自适应自动展开
    margin负值问题
    audio元素和video元素在ios和andriod中无法自动播放
    js递归
  • 原文地址:https://www.cnblogs.com/ShaYeBlog/p/3518749.html
Copyright © 2020-2023  润新知