Asp.net mvc全球化实例

imageimage

通过MVC的路由机制来实现对当前线程的区域性来设定,然后重定向请求页面来实现对已绑定数据的语言之间的切换,例如中文zh-CN,英文en-US

新建一个mvc3.0 的Internet应用程序
image

实例只针对注册页面进行多语言话,在资源文件通过键值来定义语言,2个资源文件公用一个类。通常在开发时,只要一个默认的Resource.resx,当开发完成之后,拷贝一个相同的Resource.resx,并改名字成上面的样子,然后手动或自动将其中的所有value都翻译成对应的语言。

image

image

然后是核心的类

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,就从微软现成的学起吧,上面的例子只是实现了功能。

posted @ 2012-09-26 17:10  Lordbaby  阅读(2319)  评论(3编辑  收藏  举报