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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

api接口返回动态的json格式?我太难了,尝试一下 linq to json

發布時間:2023/12/4 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 api接口返回动态的json格式?我太难了,尝试一下 linq to json 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:背景

1. 講故事

前段時間和一家公司聯調api接口的時候,發現一個奇葩的問題,它的api返回的json會動態改變,簡化如下:

{"Code":101,"Items":[{"OrderTitle":"訂單1"}]}{"Code":102,"Items":[{"ProductTitle":"商品1"}]}

邏輯是這樣的:?Items?中的內容會隨的 Code 的改變而改變,里面有可能是訂單列表又有可能是商品列表,習慣弱類型的朋友看這種json太正常不過了,但對于強類型的我們來說,簡直就是一個大寫的奇葩,你這讓我用什么強類型反序列化呢???,如果還沒理解,請看下面的這張圖吧!

經過溝通,對方果然用的是弱類型的php,磨了半天,說服讓對方改了返回結構,這樣就可以直接用固有類匹配。

二:尋找解決辦法

從業務上來說,能說服對方讓步那是最好的,但從技術上來說,這種場景有什么好的解決辦法呢?問題的本質就是json是動態的,你反序列化的時候無法指定匹配類。

1. 使用 dynamic

既然是動態的,那C#中也有一個動態類型 dynamic,何不用它來做json中動態變化的那部分的接受值,將?items?定義為 dynamic。如下圖:

從圖中看:?rsp.Items as List<OrderItem>?返回是null,嘗試失敗,雖然轉化失敗了,但我相信你也看到了?Newtonsoft.Json.Linq.JArray,貌似這玩意可以用 linq 操控,對的, 這就是?linq to json。

2. 使用 linq to json

有了linq基礎,提取JArray中內容就不難了,接下來把代碼改成如下:

static void Main(string[] args){var json = "{\"Code\":101,\"Items\":[{\"OrderTitle\":\"訂單1\"}]}";var rsp = JsonConvert.DeserializeObject<ApiResponse>(json);if (rsp.Code == 101){var items = (rsp.Items as JArray).Select(m => m["OrderTitle"].Value<string>()).ToList();Console.WriteLine(string.Join(",", items));}if (rsp.Code == 102){//todo ....}}

從代碼中可以看到,我是通過code的不同做了不同的業務邏輯處理,貌似問題通過這種半自動化的model實現了,但擁有強大好奇心的你,豈能不往下挖?

三:linq to json 分析

1. 好處

我覺得 linq to json 的最大好處就是繞過了強類型限制,可以像弱類型語言一樣處理生成和讀取json,給了我們在業務處理上更多的選擇余地,接下來我就在Create和Query上給大家拋磚引玉吧。

2. 生成json

在沒有強類型的情況下,如何構建json結構呢?對了,不知道大家對?linq to xml?還有熟悉的嗎?還記得它是怎么一步一步構建的哈,如果你記得的話,這里也是差不多的構建方式,比如說剛才的 JArray。

JObject json = new JObject(new JProperty("Code", 101),new JProperty("Items", new JArray(new JObject(){new JProperty("OrderTitle","訂單1"),new JProperty("Created",DateTime.Now)})));Console.WriteLine(json.ToString());

從圖中看這種手工構建json的方式還是比較繁瑣的,走的就是?linq to xml?的路子,有沒有更簡單的方式呢?我覺得這里你可以用 C# 中的一個語法糖:匿名類型,雖然從?IL?上看也是強類型,但在用在這里太合適了,接下來我來改造一下:

JObject json = JObject.FromObject(new{Code = 101,Items = (new[]{new { OrderTitle="訂單1",Created=DateTime.Now }}).ToList()});Console.WriteLine(json.ToString());

這樣是不是太方便了,算是巧用 匿名類型 吧。

2. 解析json

為了讓結果更可觀,我準備生成一個稍微復雜一點的json,然后通過?linq to json?和?jsonpath?兩種方式操控json。

{"store":{"book":[{"category":"reference","author":"Nigel Rees","title":"Sayings of the Century","price":8.95},{"category":"fiction","author":"Evelyn Waugh","title":"Sword of Honour","price":12.99},{"category":"fiction","author":"Herman Melville","title":"Moby Dick","isbn":"0-553-21311-3","price":8.99},{"category":"fiction","author":"J. R. R. Tolkien","title":"The Lord of the Rings","isbn":"0-395-19395-8","price":22.99}],"bicycle":{"color":"red","price":19.95}} }
  • 對 category 進行分組,統計每個類別的總金額

static void Main(string[] args){var json = System.IO.File.ReadAllText("1.txt");JObject obj = JObject.Parse(json);var dict = obj["store"]["book"].GroupBy(m => m["category"]).ToDictionary(k => k.Key,v => v.Select(n => n.Value<decimal>("price")).Sum());foreach (var key in dict.Keys){Console.WriteLine($"key={key},value={dict[key]}");}}

哈哈,分組統計在強大的linq面前就是這么簡單!

  • 使用 jsonpath 處理

jsonpath 就像 xmlpath 一樣,非常強大,更多的功能可以參考這個網頁:https://goessner.net/articles/JsonPath/。

根據上面的語法,我嘗試著提取所有的price,使用?$..price?試試。

var json = System.IO.File.ReadAllText("1.txt");JObject obj = JObject.Parse(json);var priceList= obj.SelectTokens("$..price");foreach (var price in priceList){Console.WriteLine(price.Value<decimal>());}

四:總結

我相信大家在90%的情況都是用強類型作為json的mapping,剩下的10%情況,可以了解下強大的 linq to json哈,太實用啦!希望本篇對您有幫助。

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的api接口返回动态的json格式?我太难了,尝试一下 linq to json的全部內容,希望文章能夠幫你解決所遇到的問題。

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