最近因为项目需要又从UWP开发转到了Asp.net mvc 开发,由于也不是什么老手,所以就将项目常见的一些技术问题记录一下自己的解决方案。

第一个需求:用户可以自由切换界面显示语言。

解决方案一:界面字段信息分语言保存在数据库,根据用户选择语言读取。

个人观点:由于需要经过一次数据库,相对比较慢。而且所有界面的字段数据如果一次性读取使用也占用内存,如果分页面读取更慢。

解决方案二:界面字段信息分语言保存在资源文件。

代码地址:https://github.com/NewBLife/Asp.net-MVC/tree/master/MutiLaugage

个人观点:

  • 有专门的编辑器编辑字段,相对数据库操作方便!
  • 运行时读取内嵌的二进制文件,快!

资源文件运行原理:

  • 在向 Visual Studio 项目中添加资源文件时,Visual Studio 会在项目目录中创建一个 .resx 文件。
  • 编译时,Visual Studio 首先会将项目中的 .resx 文件转换为二进制资源 (.resources) 文件,然后在项目的 obj 目录的子目录中存储这些文件。
  • Visual Studio 会将不包含本地化资源的任何资源文件嵌入项目所生成的主程序集中。  如果任何资源文件包含本地化资源,则 Visual Studio 会将它们嵌入每个本地化区域性的单独附属程序集中。  然后,它会将各个附属程序集存储在其名称与本地化区域性对应的目录中。  例如,本地化的英语(美国)资源将存储在 en-US 子目录中的附属程序集中。

资源文件的多语言实现方式

  • 路由设置。(例如:example.com/en-US/Home/Index)
  • Cookie设置。

路由设置项目实现:

1,多语言路由设置。

routes.MapRoute("DefaultLocalized",

                "{culture}/{controller}/{action}/{id}",

                new

                {

                    controller = "Home",

                    action = "Index",

                    id = "",

                    culture = "en-US"

                });

2,Request进程语言设置。

一,BaseController的BeginExecuteCore方法设置:

public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{ //string language = RouteData.Values["language"].ToString() ?? "nl";
//string culture = RouteData.Values["culture"].ToString() ?? "NL";
string cultureName = RouteData.Values["culture"] as string; // Attempt to read the culture cookie from Request
if (cultureName == null)
cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages[0] : null; // obtain it from HTTP header AcceptLanguages // Validate culture name
//cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe if (RouteData.Values["culture"] as string != cultureName)
{ // Force a valid culture in the URL
RouteData.Values["culture"] = cultureName.ToLowerInvariant(); // lower case too // Redirect user
Response.RedirectToRoute(RouteData.Values);
} // Modify current thread's cultures            Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; return base.BeginExecuteCore(callback, state);
}
}

二,Filter全局设置:

public class InternationalizationAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{ //string language = (string)filterContext.RouteData.Values["language"] ?? "nl";
//string cultureName = (string)filterContext.RouteData.Values["culture"] ?? "en-US";
string cultureName = filterContext.RouteData.Values["culture"] as string; //Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));
//Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture)); Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; }
}

3,测试

Cookie设置项目实现:

1,用户选择语言Cookie保存

public ActionResult Change(string language)
{
if (language != null)
{ Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(language);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
} HttpCookie cookie = new HttpCookie("_culture");
cookie.Value = language; Response.Cookies.Add(cookie); return View();
}

2,Request进程语言设置。

public class BaseController : Controller
{
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
// Cookie Language setting
string cultureName = string.Empty;
// Attempt to read the culture cookie from Request
HttpCookie cultureCookie = Request.Cookies["culture"];
if (cultureCookie != null)
cultureName = cultureCookie.Value;
else
cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ?
Request.UserLanguages[0] : // obtain it from HTTP header AcceptLanguages
null; // Modify current thread's cultures            Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; return base.BeginExecuteCore(callback, state);
}
}

3,测试

备注:

1,获取用户浏览器默认语言设置方法

Request.UserLanguages != null && Request.UserLanguages.Length > 0 ? Request.UserLanguages[0] : null

2,Thread.CurrentThread.CurrentCulture与Thread.CurrentThread.CurrentUICulture的区别Thread.CurrentThread.CurrentCulture:各个国家相关表示格式设置,比如 日期格式,通货格式等。Thread.CurrentThread.CurrentUICulture:决定ResourceManager读取那个资源文件。

Asp.net mvc 小试牛刀一:多语言支持的更多相关文章

  1. ASP.NET MVC下使用AngularJs语言(六):获取下拉列表的value和Text

    前面Insus.NET有在Angularjs实现DropDownList的下拉列表的功能.但是没有实现怎样获取下拉列表的value和text功能. 下面分别使用ng-click和ng-change来实 ...

  2. ASP.NET MVC下使用AngularJs语言(五):ng-selected

    这次学习ng-selected语法,这个是为DropDownList下拉列表显示默认选项. 演示从下面步骤开始 1,新建一个model: 上面#14行代码的property,数据类型为bool.即是存 ...

  3. ASP.NET MVC下使用AngularJs语言(二):ng-click事件

    程序用户交互,用户使用mouse点击,这是一个普通的功能. 在angularjs的铵钮点击命令是ng-click. 创建Angularjs的app使用前一篇<ASP.NET MVC下使用Angu ...

  4. ASP.NET MVC下使用AngularJs语言(一):Hello your name

    新春节后,分享第一个教程. 是教一位新朋友全新学习ASP.NET MVC下使用AngularJs语言. 一,新建一个空的Web项目.使用NuGet下载AngularJs和jQuery.二,配置Bund ...

  5. Pro ASP.NET MVC –第四章 语言特性精华

    C#语言有很多特性,并不是所有的程序员都了解本书我们将会使用的C#语言特性.因此,在本章,我们将了解一下作为一个好的MVC程序员需要了解C#语言的特性. 每个特性我们都只是简要介绍.如果你想深入了解L ...

  6. 在ASP.NET MVC中使用typeahead.js支持预先输入,即智能提示

    使用typeahead.js可以实现预先输入,即智能提示,本篇在ASP.NET MVC下实现.实现效果如下: 首先是有关城市的模型. public class City { public int Id ...

  7. ASP.NET MVC扩展自定义视图引擎支持多模板&动态换肤skins机制

    ASP.NET mvc的razor视图引擎是一个非常好的.NET MVC框架内置的视图引擎.一般情况我们使用.NET MVC框架为我们提供的这个Razor视图引擎就足够了.但是有时我们想在我们的项目支 ...

  8. ASP.NET MVC 扩展自定义视图引擎支持多模板&动态换肤skins机制

    ASP.NET  mvc的razor视图引擎是一个非常好的.NET  MVC 框架内置的视图引擎.一般情况我们使用.NET MVC框架为我们提供的这个Razor视图引擎就足够了.但是有时我们想在我们的 ...

  9. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...

随机推荐

  1. HTML的语义化,你需要深入了解

    有关HTML的一些基础课程,很多网站都有讲,于我而言,真正实践起来,我只要求我能够让它表现出我所想要的结果即可.然而,这种要求,对于后期的维护与测试,真的是......想起日前我们所做的这个项目,那里 ...

  2. 每天学点Java小知识【1】

    一 Java标识符和关键字 1.标识符 作用:用来标识类名.变量名.方法名.类型名.数组名.文件名的有效字符序列. 组成规则:由字母.下划线.美元符号和数字组成,且第一个字符不能是数字字符.注意:标识 ...

  3. 20155232 2016-2017-3 《Java程序设计》第5周学习总结

    20155232 2016-2017-3 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 异常处理 1.使用try和catch 将正常的流程放try块中,异常处理放catch ...

  4. Wireless Intranet Captive Portal

    Wireless Intranet Captive Portal 配置AAA服务Radius认证 radius-server key 0 radius radius-server authentica ...

  5. Hibernate(二)之Hibernate-api详解

    一.Hibernate体系结构 二.Hibernate-api详解 2.1.Configuration配置对象 Configuration是用来加载配置文件的 我们Hibernate中主要有两个配置文 ...

  6. 深入tornado中的协程

    tornado使用了单进程(当然也可以多进程) + 协程 + I/O多路复用的机制,解决了C10K中因为过多的线程(进程)的上下文切换 而导致的cpu资源的浪费. tornado中的I/O多路复用前面 ...

  7. 【 js 基础 】 深浅拷贝

    underscore的源码中,有很多地方用到了 Array.prototype.slice() 方法,但是并没有传参,实际上只是为了返回数组的副本,例如 underscore 中 clone 的方法: ...

  8. 跟着刚哥梳理java知识点——流程控制(六)

    分支结构(if…else .switch) 1.if else 语句格式 if(条件表达式){ 执行代码块; } else if(条件表达式){ 执行代码块; } else{ 执行代码块; } 2.s ...

  9. 关于Git增、删、改源地址问题

    在上篇博客中我们了解了Git的基本使用,如果你已经建立了一个远程代码库,并且遇到了远程代码库源地址修改的问题,那么这篇博客可能会帮到你. 1.如何查看当前远程Git库源地址呢? $git remote ...

  10. AngularJS学习笔记3

    6.AngularJS 控制器 AngularJS 控制器 控制 AngularJS 应用程序的数据. AngularJS 控制器是常规的 JavaScript 对象. ng-controller 指 ...