<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Newtonsoft 六個超簡單又實用的特性,值得一試 !

          共 8574字,需瀏覽 18分鐘

           ·

          2020-09-18 11:32

          一:講故事

          上一篇介紹的 6 個特性從園子里的反饋來看效果不錯,那這一篇就再帶來 6 個特性同大家一起欣賞。

          二:特性分析

          1. 像弱類型語言一樣解析 json

          大家都知道弱類型的語言有很多,如: nodejs,python,php,它們有一個??的地方就是處理json,不需要像 強類型語言 那樣還要給它配一個類,什么意思呢?就拿下面的 json 說事。


          {
          "DisplayName": "新一代算法模型",
          "CustomerType": 1,
          "Report": {
          "TotalCustomerCount": 1000,
          "TotalTradeCount": 50
          },
          "CustomerIDHash": [1,2,3,4,5]
          }

          這個 json 如果想灌到 C# 中處理,你就得給它定義一個適配的類,就如 初篇 的客戶算法模型類,所以這里就有了一個需求,能不能不定義類也可以自由解析上面這串 json 呢???哈哈,當然是可以的, 反序列化成 Dictionary 即可,就拿提取 Report.TotalCustomerCount 和 CustomerIDHash 這兩個字段演示一下。


          static void Main(string[] args)
          {
          var json = @"{
          'DisplayName': '新一代算法模型',
          'CustomerType': 1,
          'Report': {
          'TotalCustomerCount': 1000,
          'TotalTradeCount': 50
          },
          'CustomerIDHash': [1,2,3,4,5]
          }"
          ;

          var dict = JsonConvert.DeserializeObject < object, object>>(json);

          var report = dict[ "Report"] as JObject;
          var totalCustomerCount = report[ "TotalCustomerCount"];

          Console.WriteLine( $"totalCustomerCount={totalCustomerCount}");

          var arr = dict[ "CustomerIDHash"] as JArray;
          var list = arr.Select(m => m.Value< int>()).ToList();

          Console.WriteLine( $"list={string.Join(",", list)}");
          }

          2. 如何讓json中的枚舉保持更易讀的字符串型

          這句話是什么意思呢?默認情況下, SerializeObject 會將 Model 中的 Enum 變成數(shù)值型,大家都知道數(shù)值型語義性是非常差的,如下代碼所示:


          static void Main(string[] args)
          {
          var model = new ThreadModel() { ThreadStateEnum = System.Threading.ThreadState.Running };

          var json = JsonConvert.SerializeObject(model);

          Console.WriteLine(json);
          }

          class ThreadModel
          {

          public System.Threading.ThreadState ThreadStateEnum { get; set; }
          }

          對吧,確實語義特別差,那能不能直接生成 Running 這種字符串形式呢?當然可以了。。。改造如下:


          var json = JsonConvert.SerializeObject(model, new StringEnumConverter());

          這里可能就有人鉆牛角尖了,能不能部分指定讓枚舉生成 string,其他的生成 int ,沒關(guān)系,這也難不倒我,哪里使用就用 JsonConverter 標記哪里。。。


          static void Main(string[] args)
          {
          var model = new ThreadModel()
          {
          ThreadStateEnum = System.Threading.ThreadState.Running,
          TaskStatusEnum = TaskStatus.RanToCompletion
          };

          var json = JsonConvert.SerializeObject(model);

          Console.WriteLine(json);
          }

          class ThreadModel
          {

          public System.Threading.ThreadState ThreadStateEnum { get; set; }

          [JsonConverter(typeof(StringEnumConverter))]
          public TaskStatus TaskStatusEnum { get; set; }
          }

          3. 格式化 json 中的時間類型

          在 model 轉(zhuǎn)化成 json 的過程中,總少不了 時間類型,為了讓時間類型 可讀性更高,通常會 格式化為 YYYY年/MM月/dd日 ,那如何實現(xiàn)呢?很簡單撒,在 JsonConvert 中也是一個 枚舉 幫你搞定。。。


          static void Main(string[] args)
          {
          var json = JsonConvert.SerializeObject(new Order()
          {
          OrderTitle = "女裝大佬",
          Created = DateTime.Now
          }, new JsonSerializerSettings
          {
          DateFormatString = "yyyy年/MM月/dd日",
          });

          Console.WriteLine(json);
          }
          public class Order
          {

          public string OrderTitle { get; set; }
          public DateTime Created { get; set; }
          }

          對了,我記得很早的時候,C# 自帶了一個 JavaScriptSerializer, 也是用來進行 model 轉(zhuǎn) json的,但是它會將 datetime 轉(zhuǎn)成 時間戳,而不是時間字符串形式,如果你因為特殊原因想通過 JsonConvert 將時間生成時間戳的話,也是可以的, 用 DateFormatHandling.MicrosoftDateFormat 枚舉指定一下即可,如下:

          4. 對一些常用設(shè)置進行全局化

          在之前所有演示的特性技巧中都是在 JsonConvert 上指定的,也就是說 100 個 JsonConvert 我就要指定 100 次,那有沒有類似一次指定,整個進程通用呢?這么強大的 Newtonsoft 早就支持啦, 就拿上面的 Order 舉例:


          JsonConvert.DefaultSettings = () =>
          {
          var settings = new JsonSerializerSettings
          {
          Formatting = Formatting.Indented
          };
          return settings;
          };

          var order = new Order() { OrderTitle = "女裝大佬", Created = DateTime.Now };

          var json1 = JsonConvert.SerializeObject(order);
          var json2 = JsonConvert.SerializeObject(order);

          Console.WriteLine(json1);
          Console.WriteLine(json2);

          可以看到,Formatting.Indented 對兩串 json 都生效了。

          5. 如何保證 json 到 model 的嚴謹性 及提取 json 未知字段

          有時候我們有這樣的需求,一旦 json 中出現(xiàn) model 未知的字段,有兩種選擇:要么報錯,要么提取出未知字段,在 Newtonsoft 中默認的情況是忽略,場景大家可以自己找哈。

          • 未知字段報錯


          static void Main(string[] args)
          {
          var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備注'}";

          var order = JsonConvert.DeserializeObject (json, new JsonSerializerSettings
          {
          MissingMemberHandling = MissingMemberHandling.Error
          });

          Console.WriteLine(order);
          }

          public class Order
          {

          public string OrderTitle { get; set; }
          public DateTime Created { get; set; }
          public override string ToString()
          {
          return $"OrderTitle={OrderTitle}, Created={Created}";
          }
          }

          • 提取未知字段

          我依稀的記得 WCF 在這種場景下也是使用一個 ExtenstionDataObject 來存儲客戶端傳過來的未知字段,有可能是客戶端的 model 已更新,server端還是舊版本,通常在 json 序列化中也會遇到這種情況,在 JsonConvert 中使用 _additionalData 就可以幫你搞定,在 OnDeserialized 這種AOP方法中進行攔截,如下代碼:


          static void Main(string[] args)
          {
          var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備注'}";

          var order = JsonConvert.DeserializeObject (json);

          Console.WriteLine(order);
          }

          public class Order
          {

          public string OrderTitle { get; set; }

          public DateTime Created { get; set; }

          [ JsonExtensionData]
          private IDictionary< string, JToken> _additionalData;

          public Order()
          {
          _additionalData = new Dictionary< string, JToken>();
          }

          [ OnDeserialized]
          private void OnDeserialized(StreamingContext context)
          {
          var dict = _additionalData;
          }

          public override string ToString()
          {
          return $"OrderTitle={OrderTitle}, Created={Created}";
          }
          }

          6. 開啟 JsonConvert 詳細日志功能

          有時候在查閱源碼的時候開啟日志功能更加有利于理解源碼的內(nèi)部運作,所以這也是一個非常實用的功能,看看如何配置吧。


          static void Main(string[] args)
          {
          var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備注'}";

          MemoryTraceWriter traceWriter = new MemoryTraceWriter();

          var account = JsonConvert.DeserializeObject (json, new JsonSerializerSettings
          {
          TraceWriter = traceWriter
          });

          Console.WriteLine(traceWriter.ToString());
          }

          public class Order
          {

          public string OrderTitle { get; set; }

          public DateTime Created { get; set; }

          public override string ToString()
          {
          return $"OrderTitle={OrderTitle}, Created={Created}";
          }
          }

          三:總結(jié)

          嘿嘿,這篇 6 個特性就算說完了, 結(jié)合上一篇一共 12 個特性,是不是非常簡單且實用,后面準備給大家?guī)硪恍┰创a解讀吧! 希望本篇對您有幫助,謝謝!







          回復(fù) 【關(guān)閉】學(xué)關(guān)
          回復(fù) 【實戰(zhàn)】獲取20套實戰(zhàn)源碼
          回復(fù) 【被刪】學(xué)
          回復(fù) 【訪客】學(xué)
          回復(fù) 【小程序】獲取20套小程序源碼【學(xué)習(xí)+實戰(zhàn)+賺錢】
          回復(fù) 【python】學(xué)微獲取全套0基礎(chǔ)Python知識手冊
          回復(fù) 【2019】獲取2019 .NET 開發(fā)者峰會資料PPT
          回復(fù) 【加群】加入dotnet微信交流群

          2020年9月程序員工資出爐,你是否在“平均水平”以上?


          臥槽:微軟又推出新的開源網(wǎng)站!


          瀏覽 70
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  精品久久久久国产 | aaa在线免费观看 | 国产一卡二卡免费看 | 97国产超碰 | 国产精品8区 |