阳谷网站建设,杭州网站的建设,工程在哪个网站做推广比较合适,分销微信小程序开发一#xff1a;背景1. 讲故事前段时间和一家公司联调api接口的时候#xff0c;发现一个奇葩的问题#xff0c;它的api返回的json会动态改变#xff0c;简化如下#xff1a;{Code:101,Items:[{OrderTitle:订单1}]}{C… 一背景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 ListOrderItem 返回是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.DeserializeObjectApiResponse(json);if (rsp.Code 101){var items (rsp.Items as JArray).Select(m m[OrderTitle].Valuestring()).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,CreatedDateTime.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.Valuedecimal(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.Valuedecimal());}
四总结我相信大家在90%的情况都是用强类型作为json的mapping剩下的10%情况可以了解下强大的 linq to json哈太实用啦希望本篇对您有帮助。