[翻译]ASP.NET MVC 3 开发的20个秘诀(四)[20 Recipes for Programming MVC 3]:实现多语言支持
2011-12-07 11:19
946 查看
议题
互联网上有数以百万计来自数百个国家的人,同时也存在数百种不同的语言,甚至英国、美国、加拿大和英国之间也有多个不同的方言。不要让你的网站因为只提供一种语言而被限制浏览。
解决方案
创建资源文件,并添加Key/Value类型的静态文本,并实现CurrentUICulture以提供更改当前现实语言的能力。
讨论
资源文件是XML文件,可以为网站存储多国语言。当你创建一个资源文件时会包含当前默认语言。在资源中创建一个键/值对文本后,你就可以在控制器、模型和视图中随处使用了。如图例 1-3 资源文件示例。
图例 1-3,资源文件示例
右键单击应用程序,选择“添加”->“新建文件夹”,将新文件命名为“Resources”。右键单击新文件夹,选择“添加”->“新建项”。在后侧搜索中输入“资源”并选择“资源文件”。
如上图所示,我们在资源文件中创建“Book”模型类的所有属性的条目。接下来我们需要修改模型类,使用DisplayAttribute引用这些值:
在上面这个例子中,DisplayAttribute使用键名字段在资源文件中检索引用相应的资源值。这样的引用可以在每个视图以及控制器上使用。
在接下来的例子中,我们将更改书籍索引视图的现实文本,将这些静态文本移动到资源文件中。如表1-1创建键/值对表:
表 1-1 更新资源文件
目前为止只创建了一个资源文件,而其中所有的键名必须是整个项目唯一的。如你所见,在表中所创建的五个键值对,在所有视图中都可以链接使用。
将资源文件更新完成后,打开BooksController并使用下面的代码替换Index()方法:
最后,书籍的索引目录视图必须将所有的文本改为ViewBag相应属性的引用:
其他的视图和控制器都可以通过这样的方式修改,完成这些修改之后,我们只需要将资源文件复制成其他语言版本。
为了避免额外的输入,建议程序完成,所有文件都被添加到资源文件中。右键单击当前资源文件点击“复制”,然后,右键单击“Resources”文件夹点击“粘贴”,并将复制所得的资源副本文件重命名为“Resource1.fr.resx”,当然,也可以以你所希望的语言创建并命名其他副本。然后将这文件中的值得部分翻译成你所希望的语言文本。
要根据请求来变化语言,必须在Global.asax.cs文件的Appliation_AcquireRequestState()方法中通过改变每个请求的CurrentUICulture来实现:
在上面的代码示例中,经过检测之后会将有效的CultureInfo赋值给会话变量CurrentLanguage,如果为检测到有效的CultureInfo,系统会默认将英文赋予CurrentLanguage。接下来,我们会在Home控制器中创建一个动作,为用户提供选择语言的功能:
ChangeLanguage接受设置新语言名称的参数,这个参数变量会更新Global.asax.cs中的绘画变量,然后切换至用户选中语言界面。将下面的链接添加到全局共享母版页_Layout.cshtml中:
我们将链接放置在“登录”链接的旁边,这样随着网站的逐步发展,创建一个新的资源文件,添加一个新的链接,这样用户就可以选择一种新的语言了,添加一种新语言非常容易。
在之前我们讨论过加拿大、美国、英国等国家有和很多不同的英语方言,如果想为不同的国家添加语言信息,可以在国家的代码后面添加语言代码,并通过字符“-”连接起来。例如,“en-GB”表示英国英语,添加之后还需要更新链接、语言名称以及CurrentUICulture设置。
参考信息
CurrentUICulture 原书地址 书籍源代码
互联网上有数以百万计来自数百个国家的人,同时也存在数百种不同的语言,甚至英国、美国、加拿大和英国之间也有多个不同的方言。不要让你的网站因为只提供一种语言而被限制浏览。
解决方案
创建资源文件,并添加Key/Value类型的静态文本,并实现CurrentUICulture以提供更改当前现实语言的能力。
讨论
资源文件是XML文件,可以为网站存储多国语言。当你创建一个资源文件时会包含当前默认语言。在资源中创建一个键/值对文本后,你就可以在控制器、模型和视图中随处使用了。如图例 1-3 资源文件示例。
图例 1-3,资源文件示例
右键单击应用程序,选择“添加”->“新建文件夹”,将新文件命名为“Resources”。右键单击新文件夹,选择“添加”->“新建项”。在后侧搜索中输入“资源”并选择“资源文件”。
如上图所示,我们在资源文件中创建“Book”模型类的所有属性的条目。接下来我们需要修改模型类,使用DisplayAttribute引用这些值:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; using System.ComponentModel.DataAnnotations; using MvcApplication4.Validations; namespace MvcApplication4.Models { public class Book { public int ID { get; set; } [Required] [Display(Name = "TitleDisplay", ResourceType = typeof(Resources.Resource1))] public string Title { get; set; } [Display(Name = "IsbnDisplay", ResourceType = typeof(Resources.Resource1))] [Required] [IsbnValidation] public string Isbn { get; set; } [Display(Name = "SummaryDisplay", ResourceType = typeof(Resources.Resource1))] [Required] public string Summary { get; set; } [Display(Name = "AuthorDisplay", ResourceType = typeof(Resources.Resource1))] [Required] public string Author { get; set; } [Display(Name = "ThumbnailDisplay", ResourceType = typeof(Resources.Resource1))] public string Thumbnail { get; set; } [Display(Name = "PriceDisplay", ResourceType = typeof(Resources.Resource1))] [Range(1, 100)] public double Price { get; set; } [Display(Name = "PublishedDisplay", ResourceType = typeof(Resources.Resource1))] [DataType(DataType.Date)] [Required] public DateTime Published { get; set; } } public class BookDBContext : DbContext { public DbSet<Book> Books { get; set; } } }
在上面这个例子中,DisplayAttribute使用键名字段在资源文件中检索引用相应的资源值。这样的引用可以在每个视图以及控制器上使用。
在接下来的例子中,我们将更改书籍索引视图的现实文本,将这些静态文本移动到资源文件中。如表1-1创建键/值对表:
键名 | 值 |
BookIndexTitle | 索引 |
CreateLink | 创建 |
EditLink | 编辑 |
DetailsLink | 详情 |
DeleteLink | 删除 |
目前为止只创建了一个资源文件,而其中所有的键名必须是整个项目唯一的。如你所见,在表中所创建的五个键值对,在所有视图中都可以链接使用。
将资源文件更新完成后,打开BooksController并使用下面的代码替换Index()方法:
// // GET: /Books/ public ViewResult Index() { #region ViewBag Resources ViewBag.Title = Resources.Resource1.BookIndexTitle; ViewBag.CreateLink = Resources.Resource1.CreateLink; ViewBag.TitleDisplay = Resources.Resource1.TitleDisplay; ViewBag.IsbnDisplay = Resources.Resource1.IsbnDisplay; ViewBag.SummaryDisplay = Resources.Resource1.SummaryDisplay; ViewBag.AuthorDisplay = Resources.Resource1.AuthorDisplay; ViewBag.ThumbnailDisplay = Resources.Resource1.ThumbnailDisplay; ViewBag.PriceDisplay = Resources.Resource1.PriceDisplay; ViewBag.PublishedDisplay = Resources.Resource1.PublishedDisplay; ViewBag.EditLink = Resources.Resource1.EditLink; ViewBag.DetailsLink = Resources.Resource1.DetailsLink; ViewBag.DeleteLink = Resources.Resource1.DeleteLink; #endregion return View(db.Books.ToList()); }
最后,书籍的索引目录视图必须将所有的文本改为ViewBag相应属性的引用:
@model IEnumerable<MvcApplication6.Models.Book> <h2>@ViewBag.Title</h2> <p> @Html.ActionLink((string)ViewBag.CreateLink, "Create") </p> <table> <tr> <th> @ViewBag.TitleDisplay </th> <th> @ViewBag.IsbnDisplay </th> <th> @ViewBag.SummaryDisplay </th> <th> @ViewBag.AuthorDisplay </th> <th> @ViewBag.ThumbnailDisplay </th> <th> @ViewBag.PriceDisplay </th> <th> @ViewBag.PublishedDisplay </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.Isbn) </td> <td> @Html.DisplayFor(modelItem => item.Summary) </td> <td> @Html.DisplayFor(modelItem => item.Author) </td> <td> @Html.DisplayFor(modelItem => item.Thumbnail) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Published) </td> <td> @Html.ActionLink((string)ViewBag.EditLink, "Edit", new { id = item.ID }) | @Html.ActionLink((string)ViewBag.DetailsLink, "Details", new { id = item.ID }) | @Html.ActionLink((string)ViewBag.DeleteLink, "Delete", new { id = item.ID }) </td> </tr> } </table>
其他的视图和控制器都可以通过这样的方式修改,完成这些修改之后,我们只需要将资源文件复制成其他语言版本。
为了避免额外的输入,建议程序完成,所有文件都被添加到资源文件中。右键单击当前资源文件点击“复制”,然后,右键单击“Resources”文件夹点击“粘贴”,并将复制所得的资源副本文件重命名为“Resource1.fr.resx”,当然,也可以以你所希望的语言创建并命名其他副本。然后将这文件中的值得部分翻译成你所希望的语言文本。
要根据请求来变化语言,必须在Global.asax.cs文件的Appliation_AcquireRequestState()方法中通过改变每个请求的CurrentUICulture来实现:
protected void Application_AcquireRequestState( object sender, EventArgs e) { if (HttpContext.Current.Session != null) { CultureInfo ci = (CultureInfo)this.Session["CurrentLanguage"]; if (ci == null) { ci = new CultureInfo("en"); this.Session["CurrentLanguage"] = ci; } Thread.CurrentThread.CurrentUICulture = ci; Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name); } }
在上面的代码示例中,经过检测之后会将有效的CultureInfo赋值给会话变量CurrentLanguage,如果为检测到有效的CultureInfo,系统会默认将英文赋予CurrentLanguage。接下来,我们会在Home控制器中创建一个动作,为用户提供选择语言的功能:
public ActionResult ChangeLanguage(string language) { Session["CurrentLanguage"] = new CultureInfo(language); return Redirect("Index"); }
ChangeLanguage接受设置新语言名称的参数,这个参数变量会更新Global.asax.cs中的绘画变量,然后切换至用户选中语言界面。将下面的链接添加到全局共享母版页_Layout.cshtml中:
[ @Html.ActionLink("English", "ChangeLanguage", "Home", new { language = "en" }, null) ] [ @Html.ActionLink("Français", "ChangeLanguage", "Home", new { language = "fr" }, null) ]
我们将链接放置在“登录”链接的旁边,这样随着网站的逐步发展,创建一个新的资源文件,添加一个新的链接,这样用户就可以选择一种新的语言了,添加一种新语言非常容易。
在之前我们讨论过加拿大、美国、英国等国家有和很多不同的英语方言,如果想为不同的国家添加语言信息,可以在国家的代码后面添加语言代码,并通过字符“-”连接起来。例如,“en-GB”表示英国英语,添加之后还需要更新链接、语言名称以及CurrentUICulture设置。
参考信息
CurrentUICulture 原书地址 书籍源代码
相关文章推荐
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十三)[20 Recipes for Programming MVC 3]:实现Ajax增强用户体验
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十一)[20 Recipes for Programming MVC 3]:通过表单上传文件
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十)[20 Recipes for Programming MVC 3]:通过关键字进行列表搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十九)[20 Recipes for Programming MVC 3]:路由用户至特定的Controller或Action
- [翻译]ASP.NET MVC 3 开发的20个秘诀(五)[20 Recipes for Programming MVC 3]:发送欢迎邮件
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十四)[20 Recipes for Programming MVC 3]:使用Ajax提交Form
- (转)[翻译]ASP.NET MVC 3 开发的20个秘诀(十八)[20 Recipes for Programming MVC 3]:自动完成搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(七)[20 Recipes for Programming MVC 3]:对列表进行排序
- [翻译]ASP.NET MVC 3 开发的20个秘诀(九)[20 Recipes for Programming MVC 3]:对列表进行筛选
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十八)[20 Recipes for Programming MVC 3]:自动完成搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(八)[20 Recipes for Programming MVC 3]:对列表进行分页
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十六)[20 Recipes for Programming MVC 3]:站点移动化
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二十)[20 Recipes for Programming MVC 3]:缓存结果数据加速页面载入
- [翻译]ASP.NET MVC 3 开发的20个秘诀(六)[20 Recipes for Programming MVC 3]:找回忘记的密码
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十五)[20 Recipes for Programming MVC 3]:启用图片验证码(CAPTCHA)
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十七)[20 Recipes for Programming MVC 3]:卷帘式分页加载
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图
- [翻译]ASP.NET MVC 3 开发的20个秘诀(三)[20 Recipes for Programming MVC 3]:验证用户输入
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二)[20 Recipes for Programming MVC 3]:自动生成控制器和视图
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二十)[20 Recipes for Programming MVC 3]:缓存结果数据加速页面载入