博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ASP.NET MVC 多语言方案
阅读量:6307 次
发布时间:2019-06-22

本文共 3253 字,大约阅读时间需要 10 分钟。

hot3.png

前言:

好多年没写文章了,工作很忙,天天加班, 每天都相信不用多久就会升职加薪当上总经理出任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"
>
  
<
L
="zh-cn"
>中文
</
M
>
  
<
L
="en"
>English
</
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)即可。

 

总结: 

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

谢谢观赏。

转载于:https://my.oschina.net/secyaher/blog/274318

你可能感兴趣的文章
苹果将iOS应用带入macOS
查看>>
react入门
查看>>
VUE高仿饿了么app
查看>>
针对Kubernetes软件栈有状态服务设计的思考
查看>>
你的可用性达标了吗?云端业务性能高可用的深度实践
查看>>
linux yum清缓存脚本
查看>>
基于epoll封装的事件回调miniserver
查看>>
天猫高管全面解读大快消2018新零售打法
查看>>
idea springboot热部署无效问题
查看>>
第八章 进程间通信
查看>>
HttpSession接口中的方法(Jsp中的session类的用法)
查看>>
「镁客早报」AI可预测心脏病人死亡时间;机器人开始在美国送外卖
查看>>
MoQ(基于.net3.5,c#3.0的mock框架)简单介绍
查看>>
物联网全面升级,十年内推动工业进入智能化新阶段
查看>>
spring-通过ListFactory注入List
查看>>
一种基于SDR实现的被动GSM嗅探
查看>>
阿里云ECS每天一件事D1:配置SSH
查看>>
SQL Server 性能调优(性能基线)
查看>>
uva 10801 - Lift Hopping(最短路Dijkstra)
查看>>
[Java Web]servlet/filter/listener/interceptor区别与联系
查看>>