1. .net core國際化

        共 3771字,需瀏覽 8分鐘

         ·

        2020-08-30 10:02

        1、背景

          公司業(yè)務遍及全球各地,對應業(yè)務系統(tǒng)國際化就是順理成章的事情。最近就接手了一批新老系統(tǒng)的國際化任務,這里把一些探索經(jīng)驗、案例記錄下來。本身改造和探索過程包括.NET MVC的,以及.NET CORE WEB API的,但這里舊版MVC的就不描述了,重點介紹netcore下的國際化方案。國際化重點在于多語言支持,以及多時區(qū)支持,本文就從這兩個方面入手。

          預設:有一個前后端分離的系統(tǒng),前端由i18n負責多語言支持,后端不渲染視圖,提供api返回數(shù)據(jù)給前端。

          Demo解決方案截圖:

        ?

        ?

        ?

        2、多語言

          如上解決方案截圖,Common.Resource是多語言資源工程,ExceptionHandlerTest是示例web api項目,Service是api項目依賴的服務工程。之所以這么設計場景,是為了探索資源文件放在單獨工程下,以及非Web Api工程中的多語言方案,這點在官方教程中基本是沒有的。

          先來看demo要干的事情:HomeController中有個SayHello方法,此方法調(diào)用HomeService中的SayHello方法返回歡迎語信息,我們要做的就是對HomeService中返回的歡迎語進行語言協(xié)商。下邊來看看具體怎么實現(xiàn):

        ?

        2.1、定義多語言資源文件

          以支持中英文為例,定義如下圖資源文件,步驟與FX下的很類似。

        ?

        ?

          唯一的重大區(qū)別,是如果你希望在單獨工程中放置資源配置,那就添加一個單獨類代碼文件,假如你的資源是Common.en.rex,那對應類就應該是Common,這點在跨程序集尋找資源文件中至關重要,官網(wǎng)文檔中可沒有描述這至關重要的一點,別問我怎么知道的, 問就是看core底層源碼。。。

          資源文件中定義的資源配置項如下:

        ?

        ?

        ?

        ?

        ?

        ?

        ?

        2.2、配置多語言服務及中間件

        1)注冊本地化服務及HomeService服務

        ?  HomeService必須使用容器解析,否則core底層沒法注入多語言基礎服務到我們的組件,那你就只能手動傳入。

        2)注冊本地化中間件

        ?

        2.3、系統(tǒng)中引入多語言設置項

        1)HomeService中注入IStringLocalizer服務

        ?

        ?2)SayHello方法引用多語言配置項

        ?

        2.4、實際效果

        1)默認訪問

        ?

        ?

        ?不做任何設置,系統(tǒng)也無設置對應cookie情況下,netcore直接取瀏覽器語言環(huán)境設置,就是下圖這個地方:

        ?

          假如我們將瀏覽器語言環(huán)境改成英文,那默認情況下系統(tǒng)就會選取英文了。

        2)通過查詢字符串切換語言

        ?

        ?

        ?  如上圖,我們使用netcore規(guī)定的culture=en格式向后端傳遞語言環(huán)境信息。具體語言環(huán)境選擇優(yōu)先級是這樣的:查詢字符串? >? cookie ?>? 瀏覽器語言環(huán)境設置,這在官網(wǎng)有詳細介紹,看底層源碼也證實了這個?;赾ookie選取語言環(huán)境時候,cookie名稱是可以修改的,我實際項目就是如此,官網(wǎng)文檔也有介紹,這里不做贅述。

        ?

        3、多時區(qū)

        3.1、場景預設

        預設1:HomeController中有兩個方法,GetTime返回服務端或數(shù)據(jù)庫中存儲的UTC時間,系統(tǒng)根據(jù)客戶本地時區(qū)自動轉換成其對應時間;SetTime方法接收客戶本地時區(qū)下的時間,轉換成UTC時間存入服務器或數(shù)據(jù)庫

        預設2:系統(tǒng)支持中國東八區(qū)時間及印度東5區(qū)時間

        3.2、自定義時間轉換器

        /// 
        /// 日期轉換
        ///

        public class DateTimeOffsetJsonConverter : JsonConverter
        {
        private TimeZoneInfo chinaZoneInfo = TimeZoneInfo.CreateCustomTimeZone("zh", TimeSpan.FromHours(8), "中國時區(qū)", "China time zone");
        private TimeZoneInfo indiaZoneInfo = TimeZoneInfo.CreateCustomTimeZone("en-IN", TimeSpan.FromHours(5), "印度時區(qū)", "India time zone");

        public override DateTimeOffset Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
        var currentZoneInfo = Thread.CurrentThread.CurrentCulture.Name.Contains("zh") ? chinaZoneInfo : indiaZoneInfo;
        //var time1 = DateTimeOffset.Parse(reader.GetString());
        //var time2 = time1.ToOffset(currentZoneInfo.BaseUtcOffset);
        var time1 = new DateTimeOffset(DateTime.Parse(reader.GetString()), currentZoneInfo.BaseUtcOffset);
        var time2 = time1.ToUniversalTime();
        //var time3 = time2.ToUniversalTime();

        return time2;
        }

        public override void Write(Utf8JsonWriter writer, DateTimeOffset value, JsonSerializerOptions options)
        {
        var currentZoneInfo = Thread.CurrentThread.CurrentCulture.Name.Contains("zh") ? chinaZoneInfo : indiaZoneInfo;
        writer.WriteStringValue(value.ToOffset(currentZoneInfo.BaseUtcOffset).ToString(
        "yyyy-MM-dd HH:mm:ss"));
        }
        }

        ?

          如上所述,自定義時間序列化轉換器,讀取時間時,根據(jù)客戶語言環(huán)境匹配其對應時區(qū),時區(qū)中有對應UTC偏離時間信息,據(jù)此轉換成UTC時間;序列化寫入時候,同樣根據(jù)語言環(huán)境匹配時區(qū)信息,將服務器端的UTC時間按照時區(qū)偏離轉換成本地時間返給客戶端。

        3.3、時間轉換測試

        1)獲取服務器時間

        ?

        ?

        ?

        ?

        ?

        ?  其中currentTime是模擬服務器上或數(shù)據(jù)庫中取出來的UTC時間,然后什么不做直接返回,具體時間轉換交由時間轉換器負責。下邊看效果:

        中文環(huán)境時間:

        ?

        ?

        ?  可以看到,原始UTC時間2019-07-15 08:30:00在中國東八區(qū)8個小時偏離下,返給客戶端變成了16:30:00,即中國本地時間;

        英文環(huán)境:

        ?

        ?

        ?  當語言環(huán)境切換為英文,則匹配到印度東5區(qū)時區(qū)信息,UTC時間2019-07-15 08:30:00轉換成印度本地時間2019-07-15 13:30:00。

        ?

        2)寫入時間到服務器

        ?

        ?

        ?  同樣的,接收到客戶端時間后,我們業(yè)務代碼層不做任何設置,交由時間轉換器去負責,具體看效果:

        中文環(huán)境:

        ?

        ?  傳入本地時間2019-07-15 16:30:00,到了服務器,時間如下:

        ?

        ?  可以看到,中國東八區(qū)時間2019-07-15 16:30:00在服務器上轉換成UTC時間2019-07-15 08:30:00;

          同樣的本地時間,但語言環(huán)境為英語:

        ?

        ?

        ?

        ?

        ?  可以看到,印度東5區(qū)的本地時間2019-07-15 16:30:00到服務器,轉換成UTC時間2019-07-15 11:30:00。

        4、總結

          系統(tǒng)國際化的重點,在于語言環(huán)境國際化,以及多時區(qū)自適應,解決這兩點,剩下就不是啥問題了。關于時區(qū),這里是以服務器及數(shù)據(jù)庫中統(tǒng)一保存UTC時間為例,但也有一定麻煩,比如你需要后臺維護數(shù)據(jù),尤其是直接在數(shù)據(jù)庫中維護這種,就需要做本地時間和UTC時間的手動處理,除非你是英國人,身處英國,用英國的時區(qū)。針對這點可以做對應發(fā)散,例如假如系統(tǒng)中文用戶占多數(shù),運維也主要是中國員工,那就可以采取服務器或數(shù)據(jù)庫統(tǒng)一存儲中國東8區(qū)的時間,其他本地時間向中國時間進行轉換的做法,思路、解決方案是一致的。


        瀏覽 119
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 欧美熟女操逼 | 黄色视频在线免费观看网站 | 欧美成人精品激情在线视频 | 免费久久一级欧美特大黄 | 加勒比一区二区三区 |