日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Newtonsoft 六个超简单又实用的特性,值得一试 【下篇】

發布時間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Newtonsoft 六个超简单又实用的特性,值得一试 【下篇】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:講故事

上一篇介紹的 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<Dictionary<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 變成數值型,大家都知道數值型語義性是非常差的,如下代碼所示:

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 ,沒關系,這也難不倒我,哪里使用就用?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 轉化成 json 的過程中,總少不了 時間類型,為了讓時間類型 可讀性更高,通常會 格式化為?YYYY年/MM月/dd日?,那如何實現呢?很簡單撒,在 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 轉 json的,但是它會將 datetime 轉成 時間戳,而不是時間字符串形式,如果你因為特殊原因想通過?JsonConvert?將時間生成時間戳的話,也是可以的, 用 DateFormatHandling.MicrosoftDateFormat 枚舉指定一下即可,如下:

4. 對一些常用設置進行全局化

在之前所有演示的特性技巧中都是在?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 中出現 model 未知的字段,有兩種選擇:要么報錯,要么提取出未知字段,在?Newtonsoft?中默認的情況是忽略,場景大家可以自己找哈。

  • 未知字段報錯

static void Main(string[] args){var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備注'}";var order = JsonConvert.DeserializeObject<Order>(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<Order>(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 詳細日志功能

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

static void Main(string[] args){var json = "{'OrderTitle':'女裝大佬', 'Created':'2020/6/23','Memo':'訂單備注'}";MemoryTraceWriter traceWriter = new MemoryTraceWriter();var account = JsonConvert.DeserializeObject<Order>(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}";}}

三:總結

嘿嘿,這篇 6 個特性就算說完了, 結合上一篇一共 12 個特性,是不是非常簡單且實用,后面準備給大家帶來一些源碼解讀吧! 希望本篇對您有幫助,謝謝!

總結

以上是生活随笔為你收集整理的Newtonsoft 六个超简单又实用的特性,值得一试 【下篇】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。