在项目启动时,就提过需要多与语言设计。在以往的工作当中接触过多语言的设计,但是我并没有参与这个功能的设计,都是当时 的大佬们设计好的。是将语言内容存在数据库表中,这样每次都是要读取数据库中的数据,一定程度上影响了速度。不过当时用的是winfrom基本也都是内网使用,所以影响不是很明显。

现在,使用的是 WEB项目,除了面向国内还要面向国际,一开始,我也选择倾向于数据库存放语言的方式,毕竟之前有过类似的经验。后来发现通过读取表在转换到页面,工作量巨大。后面了解了一下.net的资源文件后,感觉就像的发现了新大陆。

好了,扯多了,现在来看看怎么设计一个多语言的项目结构。这里用 三种语言作为演示,分别是 简体中文 、繁体中文、英文。

首先建立语言目录、建立资源文件:

 

资源文件实际就是个XML,结构如下



<data name="品牌名称" xml:space="preserve">
<value>Brand name</value>
</data>
<data name="系列名称" xml:space="preserve">
<value>System Name</value>
</data>
<data name="平台名称" xml:space="preserve">
<value>PlatFrom Name</value>
</data>
<data name="材料照片" xml:space="preserve">
<value>Material photos</value>
</data>
<data name="请重新登录" xml:space="preserve">
<value>Please log in again</value>
</data>
<data name="查询" xml:space="preserve">
<value>Find</value>
</data>
<data name="请输品牌" xml:space="preserve">
<value>Please Brand Name</value>
</data>


 

操作步骤:

1、目录说明

Language 简体中文

Language.zh-tw 繁体

Language.en 英文

资源文件采用Key-Value的形式。系统上采用中文找英文的方式,毕竟我们国内用户基本还是用中文比较熟悉。所以,每个不同的文件里面都是以中文为key 其他语言为value。

在建立资源内容时注意要将访问修饰符改成public (重点),否则在页面上调用不到。

 

特别是中文资源包,其实中文也是当做一个语言进行查找,采用的是中文找中文的方式:

 

2、页面上设计语言切换栏

效果如下

 asp.net MVC 多语言设计_xml

为了方便大家把代码也贴出来:



<ul class="layui-nav left fast-add" lay-filter="">
<li class="layui-nav-item">
@if (languageType == "zh-cn")
{
<a href="javascript:;">简体</a>
}
else
if (languageType == "en")
{
<a href="javascript:;">English</a>
}
else
if (languageType == "zh-tw")
{
<a href="javascript:;">繁体</a>
}
else
{
<a href="javascript:;">语言栏</a>
}

<dl class="layui-nav-child">

<dd><a href="#" lang="zh-cn">简体</a></dd>
<dd><a href="#" lang="zh-tw">繁体</a></dd>
<dd><a href="#" lang="en">English</a></dd>
</dl>
</li>
</ul>


 

3、选择语言的时候界面上要触发一个方法进行切换语言

这个触发 方法使用ajax触发后端方法即可

前端脚本:



1 <script type="text/javascript">
2
3 $(document).ready(function () {
4 //切换 语言设置MVC语言环境,设置全局变量.
5 $(".layui-nav-child a").click(function () {
6 alert("hello Implant")
7 setLanguage($(this).attr("lang"));
8 })
9 function setLanguage(language) {
10 $.ajax({
11 url: "home/setGlobalLanguage?lan=" + language,
12 type: "GET",
13 cache: false,
14 success: function () {
15 location.reload();
16 }
17 })
18 }
19 })
20 </script>


 

后端方法:

//设置全局多语言ID



public void setGlobalLanguage()
{
string language = Request.QueryString["lan"];
HttpContext.Session["language_id"] = language;
}


 

后端也只是切换一些session值,但是看似没什么操作,背后却有另一番天地,在执行方法的时候先执行了拦截器,根据session获取选择的语言,然后在进行语言设置,接下来就是重点了,设置拦截器,建立一个类,并且继承ActionFilterAttribute 实现它的方法。我们主要在Action方法执行之前进行设置语言。来看看这个方法的代码:



/// <summary>
/// Action方法执行之前调用
/// </summary>
/// <param name="filterContext"></param>
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//base.OnActionExecuting(filterContext);
//filterContext.HttpContext.Response.Write("OnActionExecuting----Action方法执行之前调用执行了-" + FilterTargetName + "");
string browserLanguage = filterContext.HttpContext.Request.Headers["Accept-Language"].Split(',')[0];
if (browserLanguage.ToLower().Contains("en"))
{
browserLanguage = "en";
}
else if (browserLanguage.ToLower().Contains("cn"))
{
browserLanguage = "zh-cn";
}
else if (browserLanguage.ToLower().Contains("zh-tw"))
{
browserLanguage = "zh-tw";
}
else
{
browserLanguage = "zh-cn";
}
string sessionLanguage = filterContext.HttpContext.Session["language_id"] != null ? filterContext.HttpContext.Session["language_id"].ToString() : string.Empty;
//如果浏览器语言与session中语言不一致,以session语言为基准,设置语言环境
if (browserLanguage != sessionLanguage)
{
string language = string.Empty;
//第一次访问,session中无语言全局变量时,用览器语言设置语言环境
if (filterContext.HttpContext.Session["language_id"] == null)
{
language = browserLanguage;
filterContext.HttpContext.Session["language_id"] = browserLanguage;
}
//session中有语言全局变量时,用session中语言全局变量设置语言环境
else
{
language = filterContext.HttpContext.Session["language_id"].ToString();
}
//当前线程的语言采用哪种语言(比如zh,en等)
Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);
//决定各种数据类型是何组织,如数字与日期
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);
}


}


 

在拦截器这段代码主要是后面这两段,根据语言版本设置线程,会自动去找不同的语言资源(这个之前踩过坑,资源名称要用点“.”命名,如果报错可能是没有编译好)

//当前线程的语言采用哪种语言(比如zh,en等)

Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);

//决定各种数据类型是何组织,如数字与日期

Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);

好了到这步之后基本上功能也都准备好了。就到页面上看看如何使用这个语言

引用格式: @上层目录.文件名称.资源名.字段名

<label class="layui-form-label">@Sys.Language.Language.品牌名称</label>

解释:Sys 项目名称,Language 为文件夹名称 ,第二个Language为默认资源文件名称,最后的位字段名称(也就是前面说的中文找英文里面的中文)

来看看页面上切换效果:

 asp.net MVC 多语言设计_javascript_02

好了。到这里多语言功能也就实现了。

有疑问或者需要可以留言或者联系我,一起探讨。