• 实现MVC.NET 5的国际化


    实现国际化有三种做法:

    1. 创建资源文件。
    2. 每种语言设置一套单独的View。
    3. 1 + 2。

    通常而言,第一种方法的可维护性是最高的。因为随着项目的规模的扩大,为每种语言设置一套单独的View,前期的工作量和后期的维护成本都会太高。

    但是如果只采用资源文件的做法,在某些场合下,View的显示会出现问题,诸如一些文字次序是从右到左显示的语言,很显然仅仅更换文字内容也是不合适的。

    所以,最终采取何种方式还是要看具体的项目情况而定。接下去的内容只针对第一种做法。

    概括起来,有如下步骤:

    1. 创建资源文件
    2. Controller中添加国际化的支持
    3. 配置View

    ============ Action Now! ============

    1. 创建资源文件

        1) 不要将资源文件添加到现有的项目中,而是新建一个Class Library的项目, 这样可以在日后复用此资源文件到其它项目中。

        2) 创建资源文件。资源文件名可以自由定义,在这里我创建一个名为Resources.resx的资源文件,做为默认的资源文件,通常用于英文。然后再定义一个Resources.zh-CN.resx的资源文件,用于中文。在这里我们可以看出资源文件定义的规律,即Resources.[编码名].resx。创建结果如下:

    2. Controller中添加国际化的支持

        1) 创建BaseController文件,做为所有Controller的父类。

     1     public class BaseController : Controller
     2 
     3     {
     4 
     5         protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
     6 
     7         {
     8 
     9             string cultureName = null;
    10 
    11  
    12 
    13             // Attempt to read the culture cookie from Request
    14 
    15             HttpCookie cultureCookie = Request.Cookies["_culture"];
    16 
    17             if (cultureCookie != null)
    18 
    19                 cultureName = cultureCookie.Value;
    20 
    21             else
    22 
    23                 cultureName = Request.UserLanguages != null && Request.UserLanguages.Length > 0 ?
    24 
    25                         Request.UserLanguages[0] :  // obtain it from HTTP header AcceptLanguages
    26 
    27                         null;
    28 
    29             // Validate culture name
    30 
    31             cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe
    32 
    33  
    34 
    35             // Modify current thread's cultures           
    36 
    37             Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(cultureName);
    38 
    39             Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;
    40 
    41  
    42 
    43             return base.BeginExecuteCore(callback, state);
    44 
    45         }
    46 
    47 }

        2) 将每个Controller的父类改为BaseController。

        3) 可选。实现设置语言Cookie的方法,这样用户就可以通过自定义语言,而不是只能依赖浏览器的默认语言。

     1         public ActionResult SetCulture(string culture)
     2 
     3         {
     4 
     5             // Validate input
     6 
     7             culture = CultureHelper.GetImplementedCulture(culture);
     8 
     9             // Save culture in a cookie
    10 
    11             HttpCookie cookie = Request.Cookies["_culture"];
    12 
    13             if (cookie != null)
    14 
    15                 cookie.Value = culture;   // update cookie value
    16 
    17             else
    18 
    19             {
    20 
    21                 cookie = new HttpCookie("_culture");
    22 
    23                 cookie.Value = culture;
    24 
    25                 cookie.Expires = DateTime.Now.AddYears(1);
    26 
    27             }
    28 
    29             Response.Cookies.Add(cookie);
    30 
    31             return RedirectToAction("Index");
    32 
    33         } 

     4) 创建CultureHelper.cs。

      1     public static class CultureHelper
      2 
      3     {
      4 
      5         // Valid cultures
      6 
      7         private static readonly List<string> _validCultures = new List<string> { "af", "af-ZA", "sq", "sq-AL", "gsw-FR", "am-ET", "ar", "ar-DZ", "ar-BH", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA", "ar-SY", "ar-TN", "ar-AE", "ar-YE", "hy", "hy-AM", "as-IN", "az", "az-Cyrl-AZ", "az-Latn-AZ", "ba-RU", "eu", "eu-ES", "be", "be-BY", "bn-BD", "bn-IN", "bs-Cyrl-BA", "bs-Latn-BA", "br-FR", "bg", "bg-BG", "ca", "ca-ES", "zh-HK", "zh-MO", "zh-CN", "zh-Hans", "zh-SG", "zh-TW", "zh-Hant", "co-FR", "hr", "hr-HR", "hr-BA", "cs", "cs-CZ", "da", "da-DK", "prs-AF", "div", "div-MV", "nl", "nl-BE", "nl-NL", "en", "en-AU", "en-BZ", "en-CA", "en-029", "en-IN", "en-IE", "en-JM", "en-MY", "en-NZ", "en-PH", "en-SG", "en-ZA", "en-TT", "en-GB", "en-US", "en-ZW", "et", "et-EE", "fo", "fo-FO", "fil-PH", "fi", "fi-FI", "fr", "fr-BE", "fr-CA", "fr-FR", "fr-LU", "fr-MC", "fr-CH", "fy-NL", "gl", "gl-ES", "ka", "ka-GE", "de", "de-AT", "de-DE", "de-LI", "de-LU", "de-CH", "el", "el-GR", "kl-GL", "gu", "gu-IN", "ha-Latn-NG", "he", "he-IL", "hi", "hi-IN", "hu", "hu-HU", "is", "is-IS", "ig-NG", "id", "id-ID", "iu-Latn-CA", "iu-Cans-CA", "ga-IE", "xh-ZA", "zu-ZA", "it", "it-IT", "it-CH", "ja", "ja-JP", "kn", "kn-IN", "kk", "kk-KZ", "km-KH", "qut-GT", "rw-RW", "sw", "sw-KE", "kok", "kok-IN", "ko", "ko-KR", "ky", "ky-KG", "lo-LA", "lv", "lv-LV", "lt", "lt-LT", "wee-DE", "lb-LU", "mk", "mk-MK", "ms", "ms-BN", "ms-MY", "ml-IN", "mt-MT", "mi-NZ", "arn-CL", "mr", "mr-IN", "moh-CA", "mn", "mn-MN", "mn-Mong-CN", "ne-NP", "no", "nb-NO", "nn-NO", "oc-FR", "or-IN", "ps-AF", "fa", "fa-IR", "pl", "pl-PL", "pt", "pt-BR", "pt-PT", "pa", "pa-IN", "quz-BO", "quz-EC", "quz-PE", "ro", "ro-RO", "rm-CH", "ru", "ru-RU", "smn-FI", "smj-NO", "smj-SE", "se-FI", "se-NO", "se-SE", "sms-FI", "sma-NO", "sma-SE", "sa", "sa-IN", "sr", "sr-Cyrl-BA", "sr-Cyrl-SP", "sr-Latn-BA", "sr-Latn-SP", "nso-ZA", "tn-ZA", "si-LK", "sk", "sk-SK", "sl", "sl-SI", "es", "es-AR", "es-BO", "es-CL", "es-CO", "es-CR", "es-DO", "es-EC", "es-SV", "es-GT", "es-HN", "es-MX", "es-NI", "es-PA", "es-PY", "es-PE", "es-PR", "es-ES", "es-US", "es-UY", "es-VE", "sv", "sv-FI", "sv-SE", "syr", "syr-SY", "tg-Cyrl-TJ", "tzm-Latn-DZ", "ta", "ta-IN", "tt", "tt-RU", "te", "te-IN", "th", "th-TH", "bo-CN", "tr", "tr-TR", "tk-TM", "ug-CN", "uk", "uk-UA", "wen-DE", "ur", "ur-PK", "uz", "uz-Cyrl-UZ", "uz-Latn-UZ", "vi", "vi-VN", "cy-GB", "wo-SN", "sah-RU", "ii-CN", "yo-NG" };
      8 
      9         // Include ONLY cultures you are implementing
     10 
     11         private static readonly List<string> _cultures = new List<string> {
     12 
     13             "zh-CN",
     14 
     15             "en-US",
     16 
     17         };
     18 
     19         /// <summary>
     20 
     21         /// Returns true if the language is a right-to-left language. Otherwise, false.
     22 
     23         /// </summary>
     24 
     25         public static bool IsRighToLeft()
     26 
     27         {
     28 
     29             return System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.IsRightToLeft;
     30 
     31  
     32 
     33         }
     34 
     35         /// <summary>
     36 
     37         /// Returns a valid culture name based on "name" parameter. If "name" is not valid, it returns the default culture "en-US"
     38 
     39         /// </summary>
     40 
     41         /// <param name="name" />Culture's name (e.g. en-US)</param>
     42 
     43         public static string GetImplementedCulture(string name)
     44 
     45         {
     46 
     47             // make sure it's not null
     48 
     49             if (string.IsNullOrEmpty(name))
     50 
     51                 return GetDefaultCulture(); // return Default culture
     52 
     53             // make sure it is a valid culture first
     54 
     55             if (_validCultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Count() == 0)
     56 
     57                 return GetDefaultCulture(); // return Default culture if it is invalid
     58 
     59             // if it is implemented, accept it
     60 
     61             if (_cultures.Where(c => c.Equals(name, StringComparison.InvariantCultureIgnoreCase)).Count() > 0)
     62 
     63                 return name; // accept it
     64 
     65             // Find a close match. For example, if you have "en-US" defined and the user requests "en-GB",
     66 
     67             // the function will return closes match that is "en-US" because at least the language is the same (ie English) 
     68 
     69             var n = GetNeutralCulture(name);
     70 
     71             foreach (var c in _cultures)
     72 
     73                 if (c.StartsWith(n))
     74 
     75                     return c;
     76 
     77             // else
     78 
     79             // It is not implemented
     80 
     81             return GetDefaultCulture(); // return Default culture as no match found
     82 
     83         }
     84 
     85         /// <summary>
     86 
     87         /// Returns default culture name which is the first name decalared (e.g. en-US)
     88 
     89         /// </summary>
     90 
     91         /// <returns></returns>
     92 
     93         public static string GetDefaultCulture()
     94 
     95         {
     96 
     97             return _cultures[0]; // return Default culture
     98 
     99         }
    100 
    101         public static string GetCurrentCulture()
    102 
    103         {
    104 
    105             return Thread.CurrentThread.CurrentCulture.Name;
    106 
    107         }
    108 
    109         public static string GetCurrentNeutralCulture()
    110 
    111         {
    112 
    113             return GetNeutralCulture(Thread.CurrentThread.CurrentCulture.Name);
    114 
    115         }
    116 
    117         public static string GetNeutralCulture(string name)
    118 
    119         {
    120 
    121             if (name.Length < 2)
    122 
    123                 return name;
    124 
    125             return name.Substring(0, 2); // Read first two chars only. E.g. "en", "es"
    126 
    127         }
    128 
    129 }

    注意_cultures数组里的是当前系统支持的语言。

    3. 配置View

        1) 在MVC项目中添加对Resources项目的引用。

        2) 修改View目录下的web.config文件,在pages下添加namespace=Resources。这样在View中就能够直接引用Resources。

     1     <pages pageBaseType="System.Web.Mvc.WebViewPage">
     2 
     3       <namespaces>
     4 
     5         <add namespace="System.Web.Mvc" />
     6 
     7         <add namespace="System.Web.Mvc.Ajax" />
     8 
     9         <add namespace="System.Web.Mvc.Html" />
    10 
    11         <add namespace="System.Web.Optimization"/>
    12 
    13         <add namespace="System.Web.Routing" />
    14 
    15         <add namespace="Resources" />
    16 
    17       </namespaces>
    18 
    19     </pages>

    3)       在View中需要的地方写@Resources.[key]。例如:

    1 <div class="jumbotron">
    2 
    3     <h1>@Resources.ApplicationName</h1>
    4 
    5     <p><a href="http://asp.net" class="btn btn-primary btn-large">@Resources.Expose</a></p>
    6 
    7 </div>

    完工。本文忽略了设置语言的前端实现,和后台的资源文件内容的提取。如果有想要知道的朋友,可以提出来,我会另外再写一篇做介绍。

  • 相关阅读:
    支付宝校园一卡通充值服务体验
    商品筛选导航菜单亮点欣赏
    手机QQ v4.2 有感
    因所缺,而所需——互联网应用的开发方向
    浅谈 css3 box盒子模型以及box-flex的使用
    浅谈stylus与sass的对比
    css3 transfrom使用以及其martix(矩阵)属性与其它属性的关系
    js命名空间
    公用的stringUtil工具
    js 实现angylar.js view层和model层双绑定(改变view刷新 model,改变model自动刷新view)
  • 原文地址:https://www.cnblogs.com/ilovewindy/p/3737400.html
Copyright © 2020-2023  润新知