• Asp.net mvc 小试牛刀一:多语言支持


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

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

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

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

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

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

    image

    个人观点:

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

    资源文件运行原理:

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

    image

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

    • 路由设置。(例如: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,测试

    LanguageMultiple

    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,测试

    LanguageMultiple2

    备注:

    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读取那个资源文件。

  • 相关阅读:
    Linux 下使用gettimeofday函数时已添加time.h后,还是报找不到gettimeofday函数问题
    记录linux编译opencv时报错: relocation R_X86_64_PC32 against symbol `XXXX' can not be used when making a shared object; recompile with fPIC
    记录Linux 没有声音/Gnome 没有声音输出设备问题
    c#抓屏(截屏)
    抽象类与接口区别 (收集)
    种方式遍历repeater中的CheckBox全选
    .net 发送电子邮件
    Repeater 双向排序
    通过SessionID和用户名来保证同一个用户不能同时登录
    ASP.NET页面刷新方法总结
  • 原文地址:https://www.cnblogs.com/lixiaobin/p/AspnetMVCMultipleLanguage.html
Copyright © 2020-2023  润新知