Asp.net mvc全球化实例
通过MVC的路由机制来实现对当前线程的区域性来设定,然后重定向请求页面来实现对已绑定数据的语言之间的切换,例如中文zh-CN,英文en-US
实例只针对注册页面进行多语言话,在资源文件通过键值来定义语言,2个资源文件公用一个类。通常在开发时,只要一个默认的Resource.resx,当开发完成之后,拷贝一个相同的Resource.resx,并改名字成上面的样子,然后手动或自动将其中的所有value都翻译成对应的语言。
然后是核心的类
LocalizationHelpers的主要代码:
using System; using System.Collections.Generic; using System.Linq; using System.Resources; using System.Web; using System.Web.Mvc; using System.Web.WebPages; using System.Threading; using Language; using System.Collections; using System.Runtime.Caching; namespace MvcApp.Extensions { public static class LocalizationHelpers { public static readonly ResourceManager recourseManager = new ResourceManager(typeof(Resource)); public static IHtmlString MetaAcceptLanguage<T>(this HtmlHelper<T> html) { var acceptLanguage = HttpUtility.HtmlAttributeEncode(System.Threading.Thread.CurrentThread.CurrentUICulture.ToString()); return new HtmlString(String.Format("<meta name='accept-language' content='{0}'>", acceptLanguage)); } /// <summary> /// 本地化获取资源值方法,用于web页面 /// </summary> /// <param name="htmlhelper"></param> /// <param name="key"></param> /// <returns></returns> public static string Lang(this HtmlHelper htmlhelper, string key) { return Lang(htmlhelper.ViewDataContainer as WebViewPage, key); } /// <summary> /// 本地化获取资源值方法,用于web页面 /// </summary> /// <param name="page"></param> /// <param name="key"></param> /// <returns></returns> public static string Lang(this WebPageBase page, string key) { try { string cultureName = null; if (page.Session["Culture"] != null) { cultureName = Thread.CurrentThread.CurrentCulture.Name; } else { //默认设置为中文 cultureName = "zh-CN"; Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName); Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture; page.Session["Culture"] = Thread.CurrentThread.CurrentCulture; } IEnumerable<DictionaryEntry> resxs = null; resxs = GetResx(cultureName); return (string)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value; } catch { return "?"; } } /// <summary> /// 当前web环境线程中,获取资源键值 /// </summary> /// <param name="key"></param> /// <returns></returns> public static string Toi18nString(string key) { IEnumerable<DictionaryEntry> resxs = null; resxs = GetResx(System.Threading.Thread.CurrentThread.CurrentUICulture.Name); return (string)resxs.FirstOrDefault<DictionaryEntry>(x => x.Key.ToString() == key).Value; } /// <summary> /// 当前web环境线程中,获取资源视图 /// </summary> /// <param name="resxKey"></param> /// <returns></returns> private static IEnumerable<DictionaryEntry> GetResx(string resxKey) { ObjectCache cache = MemoryCache.Default; IEnumerable<DictionaryEntry> resxs = null; if (cache.Contains(resxKey)) { resxs = cache.GetCacheItem(resxKey).Value as IEnumerable<DictionaryEntry>; } else { ResourceManager resource =new ResourceManager(typeof(Resource)); var resourceSet = resource.GetResourceSet( Thread.CurrentThread.CurrentUICulture, true, true); if (resourceSet != null) { resxs = resourceSet.Cast<DictionaryEntry>(); cache.Add(resxKey, resxs, new CacheItemPolicy() { Priority = CacheItemPriority.NotRemovable }); } } return resxs; } } }
然后是重写DisplayName特性
using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Web; namespace MvcApp.Extensions { public class LocalizedDisplayNameAttribute : DisplayNameAttribute { public LocalizedDisplayNameAttribute(string resourceKey) { ResourceKey = resourceKey; } public override string DisplayName { get { string displayName = LocalizationHelpers.Toi18nString(ResourceKey);//MyResource.ResourceManager.GetString(ResourceKey); return string.IsNullOrEmpty(displayName) ? string.Format("[[{0}]]", ResourceKey) : displayName; } } private string ResourceKey { get; set; } } }
在model层所需要实现多语言的字段带个帽子
public class RegisterModel { [Required] [LocalizedDisplayName("UserName")] public string UserName { get; set; } [Required] [DataType(DataType.EmailAddress)] [LocalizedDisplayName("EmailAddress")] public string Email { get; set; } [Required] [StringLength(100, ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "passwordlength", MinimumLength = 6)] [DataType(DataType.Password)] [LocalizedDisplayName("Password")] public string Password { get; set; } [DataType(DataType.Password)] [LocalizedDisplayName("confirmPwd")] [System.Web.Mvc.Compare("Password", ErrorMessageResourceType = typeof(Resource), ErrorMessageResourceName = "comparepassword")] public string ConfirmPassword { get; set; } }
如果是必须字段可以通过ErrorMessageResourceType和ErrorMessageResourceName来自定义语言,也可以通过微软自带的Jquery的验证也实现了多语言。
语言之间的切换是通过改变区域性的Controller来实现的
public class EnglishController : Controller { // // GET: /English/ public ActionResult Index() { System.Globalization.CultureInfo englishCulture = new System.Globalization.CultureInfo("en-US"); Session["Culture"] = englishCulture; return this.Redirect(this.Request.UrlReferrer.ToString()); } }
以前只是了解MVC这个东东,项目中用到了现在打算开始学习一下MVC,就从微软现成的学起吧,上面的例子只是实现了功能。