ASP.NET MVC之国际化(十一)
前言
在项目中遇到国际化语言的问题是常有的事情,之前在做关于MVC国际化语言时,刚开始打算全部利用AngularJS来实现,但是渐渐发现对于页面Title难以去控制其语言转换,于是对于页面Tiltle利用后台的资源文件来实现而前台利用AngularJS来实现,这样更好简洁和方便,本节我们来讲讲MVC中的国际化问题。
话题引入
为了效率的问题全部利用前端脚本实现是个不错的选择,但是有时候也稍显麻烦一点,本文只讨论利用MVC来实现,下面我们首先来看一个例子。
我们在项目新建一个il8n文件夹在此下面新建一个资源文件【注意:将访问修饰符修改为public】

接下来我们新建一个【 InternationalizationController 控制器】 ,在此下面获取其资源文件的键对应的值
Assembly myAssem = Assembly.GetExecutingAssembly();
ResourceManager rm = new ResourceManager("ASP.NET_MVC_7.il8n.Resource.zh-cn", myAssem); ViewBag.title = rm.GetString("Cnblogs");
ViewBag.blog = rm.GetString("BlogName");
ViewBag.sign = rm.GetString("MySignature");
我们首先调试来看看是否已经获取到值。

错误详细如下:
其他信息: 未能找到任何适合于指定的区域性或非特定区域性的资源。请确保在编译时已将“ASP.NET_MVC_7.il8n.Resource.zh-cn.resources”正确嵌入或链接到程序集“ASP.NET MVC_7”,或者确保所有需要的附属程序集都可加载并已进行了完全签名。
出现此错误时不知所以然,经查资料有说,查看在项目的obj/debug(看项目运行模式选择对应模式即可)下是否有有对应的一扩展名 .resources 结尾的文件,若有则复制除开以扩展名的字符串,先看是否有相应的文件吧,如下:

看到这里复制这里的内容和代码里写的是一致的,还是无解。思前想后,看看这个 ResourceManager 类的参数具体是指的什么意思,第一个是basename,提示也说的不是太明确,还是看看msdn上的说明是否有注意的地方。果不其然。看看如下:

资源文件名称不能有任何扩展名,看之前我们的名称,我在第一次演示创建资源文件时就已经在左上角明确标出,其创建的资源名称为 Resource.zh-cn.resx ,上述注意本意就是说只能有一个.结尾的资源名称,我们现在将Resource.去掉再看看,代码也进行相应的修改如下。
ResourceManager rm = new ResourceManager("ASP.NET_MVC_7.il8n.zh-cn", myAssem);
之前为如下,对比一下:
ResourceManager rm = new ResourceManager("ASP.NET_MVC_7.il8n.Resource.zh-cn", myAssem);
我们在对应的视图给出如下代码:
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.title</title>
</head>
<body>
<h1>@ViewBag.blog</h1>
<h3>@ViewBag.sign</h3>
</body>
</html>
我们完整来看看最终效果:

注意:在创建资源文件命名时必须以一个扩展名命名,要么以下划线来命名。
当然为了方便管理可以将资源文件单独建立成一个项目,此时只需要加载对应的项目程序集即可,例如 :
var il8mAssem = Assembly.Load("Il8nResource");
ResourceManager rm = new ResourceManager("Il8nResource.zh-cn", il8nAssem);
var blog = rm.GetString("BlogName");
MVC实现国际化
实现国际化选择语言无非两种形式:
(1)通过下拉框自己选择语言。
(2)根据用户的pc或者phone的语言来选择对应的语言进行翻译。
本文以下拉框来展示。在此之前我们首先需要了解下国际化,国际化是什么,不就是不同国家之间的语言么,恩,是的,如果你不是干计算机的,我会马上认同你,否则就有点鄙视你了。我们接下来来看看。
国际化
国际化被缩写为i18n,i18n又是代表什么鬼玩意,它代表从i到n的18中字母。国际化用来开发产品或者软件,在这种情况下它们很容易被本地化为语言和文化,它又分为全球化和本地化。
(1)Globalization:全球化被缩写为G11n,代表以G到n的11的字母,在开发产品或者软件时使得它们可以支持不同的文化的方式处理。
(2)Localization:本地化被缩写为L10n,代表从L到n的10的字母,在开发产品或者软件时可以定制为特定的文化。
在ASP.NET Framework中的文化
在ASP.NET中有两种文化: Culture 和 UICulture ,用两个小写字母来定义语言,两个大写字母来定义区域。例如,en代表英语,而GB和US分别代表Britain(英国)和American (美国),所以在这种情况下,在英国则被定义为en-GB,在美国定义为en-US。
Culture:代表相关文化的功能,如日期、数字、货币等。
UICulture:被用来定位正确的资源文件, 并通过ResourceManager类来在网页上呈现。
这两种文化属性在.NET中的每个线程中都有,当需要呈现时通过ASP.NET 框架来处理。
国际化在MVC中
大概思路:将语言存储在Session中,通过下拉框读取资源文件更改语言。接下来我们开始实现。
(1)新建一个项目 InternationalizationResources 并在其下创建中文和英文资源文件。


(2)创建用户注册类,并利用DataAnnotations中的 ResourceType 来对应其默认资源类型(中文)
public class UserViewModel
{
[Display(Name = "UserName", ResourceType = typeof(InternationalizationResources.Resource))]
[Required(ErrorMessageResourceName = "UserNameRequired", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
public string UserName { get; set; } [Display(Name = "FullName", ResourceType = typeof(InternationalizationResources.Resource))]
[Required(ErrorMessageResourceName = "NameRequired", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
public string FullName { get; set; } [Display(Name = "Password", ResourceType = typeof(InternationalizationResources.Resource))]
[Required(ErrorMessageResourceName = "PasswordRequired", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
public string Password { get; set; } [Display(Name = "ConfirmPassword", ResourceType = typeof(InternationalizationResources.Resource))]
[Required(ErrorMessageResourceName = "ConfirmPasswordRequired", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
[Compare("Password", ErrorMessageResourceName = "ConfirmPasswordCompare", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
public string ConfirmPassword { get; set; } [Display(Name = "Address", ResourceType = typeof(InternationalizationResources.Resource))]
[Required(ErrorMessageResourceName = "AddressRequired", ErrorMessageResourceType = typeof(InternationalizationResources.Resource))]
public string Address { get; set; }
}
(3)在初始化时设置文化。
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
base.Initialize(requestContext);
if (Session["CurrentCulture"] != null)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(Session["CurrentCulture"].ToString());
Thread.CurrentThread.CurrentUICulture = new CultureInfo(Session["CurrentCulture"].ToString());
}
}
(4)通过下拉框存储语言。
public ActionResult ChangeCulture(string ddlCulture)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(ddlCulture);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(ddlCulture); Session["CurrentCulture"] = ddlCulture;
return View("Index");
}
(5)用户注册并验证。
[HttpPost]
public ActionResult Index(UserViewModel user)
{
if (ModelState.IsValid)
{ }
return View();
}
(6)利用强类型视图首先获取页面标题。
@model ASP.NET_MVC_7.Models.UserViewModel
@{
ViewBag.Title = InternationalizationResources.Resource.Title;
}
(7)读取资源文件中语言并设置到下拉框并给其选择语言更换语言事件。
<div class="col-md-4">
@using (Html.BeginForm("ChangeCulture", "Internationalization"))
{
<p>
@InternationalizationResources.Resource.SelectLanuage : @Html.DropDownList("ddlCulture", new SelectList(new[]
{
new{value="zh-CN",text= InternationalizationResources.Resource.Chinese},
new{value="en-Us",text= InternationalizationResources.Resource.English} }, "value", "text", Session["CurrentCulture"]), new { onchange = "this.form.submit();" })
</p>
}
</div>
(8)进行注册并验证。
<br />
@using (Html.BeginForm("Index", "Internationalization"))
{
@Html.AntiForgeryToken() <div class="form-horizontal"> @Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
@Html.LabelFor(model => model.FullName, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.FullName, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.FullName, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
@Html.LabelFor(model => model.Password, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.PasswordFor(model => model.Password, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Password, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
@Html.LabelFor(model => model.ConfirmPassword, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.PasswordFor(model => model.ConfirmPassword, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.ConfirmPassword, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
@Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.TextAreaFor(model => model.Address, new { @class = "form-control" })
@Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
</div>
</div> <div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="@InternationalizationResources.Resource.Save" class=" btn btn-default" />
</div>
</div>
</div>
}
下面我们来完整看看演示效果:

总结
这一节我们学习了如何在MVC中如何实现国际化,注意:一般我们可以设置一个默认的语言如上述的Resource.Resx(中文),而英文必须以Resource以开头后面紧跟语言如(Resource.en-US.resx)才行。当页面中需要的翻译的不多时可以直接通过 ResourceManager 类来实现,但是上述也讲了需要注意的地方。
ASP.NET MVC之国际化(十一)的更多相关文章
- 学习ASP.NET MVC(十一)——分页
在这一篇文章中,我们将学习如何在MVC页面中实现分页的方法.分页功能是一个非常实用,常用的功能,当数据量过多的时候,必然要使用分页.在今天这篇文章中,我们学习如果在MVC页面中使用PagedList. ...
- ASP.NET MVC 4 (十一) Bundles和显示模式--asp.net mvc中 @Scripts.Render("~/bundles/jquery")是什么意思? 在布局文件中使用Scripts.Render()输出脚本包,Styles.Render()输出风格包:
ASP.NET MVC 4 (十一) Bundles和显示模式 ASP.NET MVC 4 引入的js打包压缩功能.打包压缩jquery目录下的文件,在布局文件中使用Scripts.Render()输 ...
- ASP.NET MVC 4 (十一) Bundles和显示模式
Bundles用于打包CSS和javascript脚本文件,优化对它们的组织管理.显示模式则允许我们为不同的设备显示不同的视图. 默认脚本库 在VS创建一个MVC工程,VS会为我们在scripts目录 ...
- 跟我学ASP.NET MVC之十一:URL路由
摘要: 在MVC框架之前,ASP.NET假定在请求的URLs和服务器硬盘文件之间有直接的关系.服务器的职责是接收浏览器请求,从相应的文件发送输出. 这种方法只能工作于Web表单,每一个ASPX页面既是 ...
- ASP.NET MVC Filters 4种默认过滤器的使用【附示例】
过滤器(Filters)的出现使得我们可以在ASP.NET MVC程序里更好的控制浏览器请求过来的URL,不是每个请求都会响应内容,只响应特定内容给那些有特定权限的用户,过滤器理论上有以下功能: 判断 ...
- Asp.Net MVC+BootStrap+EF6.0实现简单的用户角色权限管理
这是本人第一次写,写的不好的地方还忘包含.写这个的主要原因是想通过这个来学习下EF的CodeFirst模式,本来也想用AngularJs来玩玩的,但是自己只会普通的绑定,对指令这些不是很熟悉,所以就基 ...
- 学习ASP.NET MVC(七)——我的第一个ASP.NET MVC 查询页面
在本篇文章中,我将添加一个新的查询页面(SearchIndex),可以按书籍的种类或名称来进行查询.这个新页面的网址是http://localhost:36878/Book/ SearchIndex. ...
- asp.net mvc笔记一,最小的MVC工程
Asp.net MVC项目默认会引用很多第三方插件,特别是现在的5.0,默认示例项目就几十M,搞得都不知道那些才是MVC必须的,是重点,那些是可有可无的. 今天我们就来试验一下,看看一个最小的MVC工 ...
- Datatables 在asp.net mvc中的使用
前言 最近使用ABP(ASP.NET Boilerplate)做新项目,以前都是自己扩展一个HtmlHelper来完成同步/异步分页,但是有个地方一直不满意,排序太费劲. 以前接触过一点点的Datat ...
随机推荐
- BZOJ4455: [Zjoi2016]小星星
Description 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细 线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这 ...
- css3媒体查询实现网站响应式布局
最常见的办法就是基类(最常用的网站布局)+扩展类(几种不同的网站布局类)来实现不同的布局. <!–使用说明:网站基本布局,使用class="layout";使用ipad访问时 ...
- WIN32 窗口类封装 框架实现部分
上面已经讲了窗口封装部分,内容可点击:http://www.cnblogs.com/mengdejun/p/4010320.html,下面分享框架部分内容,完成WINDOWS消息迭代 CQFrameW ...
- iOS开发之记录用户登录状态
iOS开发之记录用户登录状态 我们知道:CoreData的配置和使用步骤还是挺复杂的.但熟悉CoreData的使用流程后,CoreData还是蛮好用的.今天要说的是如何记录我们用户的登陆状态.例如微信 ...
- CF2.C
C. Vladik and fractions time limit per test 1 second memory limit per test 256 megabytes input stand ...
- Centos 6.5 搭建l2tp 服务端和客户端
废话不多说直接上步骤. server #epel仓库愿安装 rpm -ivh http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release- ...
- properties文件使用{0}...
例如properties文件的配置 weixin.token.url=https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credent ...
- nodemailer 发邮件
var transporter = nodemailer.createTransport({//v1.0 above do not use 'SMTP' as first param host: &q ...
- eclipse构建maven的web项目
如果以后要创建maven的web项目,可以参考这个链接 http://blog.csdn.net/smilevt/article/details/8215558/
- SQL Server差异备份的备份/还原原理
SQL Server差异备份的备份/还原原理 记住一点:差异备份是基于最后一次完整备份的差异,而不是基于最后一次差异的差异 备份过程: 1-完整备份之后有无对数据库做过修改,如果有,记录数据库的最 ...