一:背景

1. 讲故事

在开始本文之前,真的好想做个问卷调查,到底有多少人和我一样,对 JsonConvert 的认识只局限在 SerializeObject 和 DeserializeObject 这两个方法上(┬_┬), 这样我也好结伴同行,不再孤单落魄????????????,或许是这两个方法基本上能够解决工作中 80% 的场景,对于我来说确实是这样,但随着编码的延续,终究还是会遇到那剩下的 20% ,所以呀。。。

我的场景是这样的:前段时间写业务代码的时候,我有一个自定义的客户算法类型的Model,这个Model中有这种算法类型下的客户群以及Report统计信息,还用了 HashSet 记录了该类型下的 CustomerID集合,为了方便讲述,我把Model简化如下:

class CustomerAlgorithmModel{public string DisplayName { get; set; }public int CustomerType { get; set; }public ReprotModel Report { get; set; }public HashSet<int> CustomerIDHash { get; set; }}class ReprotModel{public int TotalCustomerCount { get; set; }public int TotalTradeCount { get; set; }}

那有意思的就来了,我个人是有记日志的癖好,就想着以后不会出现死无对证的情况,然后就理所当然的使用 JsonConvert.SerializeObject, 这一下就出问题了,日志送入到了 ElasticSearch ,然后通过 Kibana 查不出来,为啥呢?看完上面的 Model 我想你也猜到了原因,json体太大了哈,好歹 CustomerIDHash 中也有几十万个撒,这一下全导出成json了,这 size 还能小吗?要不我写段代码看一看。

static void Main(string[] args){var algorithModel = new CustomerAlgorithmModel(){CustomerType = 1,DisplayName = "????????",Report = new ReprotModel(){TotalCustomerCount = 1000,TotalTradeCount = 50},CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000))};var json = JsonConvert.SerializeObject(algorithModel);File.WriteAllText("1.txt", json, Encoding.UTF8);Console.WriteLine("写入完成!");}

可以看到,仅一个json就 3.3M,这样的记录多来几打后,在 kibana 上一检索,浏览器就卡的要死,其实 CustomerIDHash 这个字段对我来说是可有可无的,就算存下来了也没啥大用,所以需求就来了,如何屏蔽掉 CustomerIDHash

二:寻求解决方案

1. 使用 JsonIgnore

有问题就网上搜啊,这一搜马上就有人告诉你可以使用 JsonIgnoreAttribute 忽略特性,加好这个特性后继续跑一下程序。

[Newtonsoft.Json.JsonIgnore]public HashSet<int> CustomerIDHash { get; set; }

太好了,终于搞定了,但是静下心来想一想,总感觉心里有那么一点不舒服,为什么这么说,一旦你给这个 CustomerIDHash 套上了 JsonIgnore ,这就意味着它在 JsonConvet 的世界中从此消失,也不管是谁在使用这个Model, 但这并不是我的初衷,我的初衷仅仅是为了在记录日志的时候踢掉 CustomerIDHash,可千万不要影响在其他场景下的使用哈,现在这种做法就会给自己,给别人挖坑,埋下了不可预知的bug,我想你应该明白我的意思,还得继续寻找下一个方案。

2. 使用自定义的 JsonConverter

真的,Newtonsoft 太强大了,我都想写一个专题好好弥补弥补我的知识盲区,其实在这个场景中不就是想把 HashSet<int> 给屏蔽掉嘛,Newtonsoft 中专门提供了一个针对特定类型的自定义处理类,接下来我就写一段:

/// <summary>/// 自定义一个 针对 HashSet<int> 的转换类/// </summary>public class HashSetConverter : Newtonsoft.Json.JsonConverter<HashSet<int>>{public override HashSet<int> ReadJson(JsonReader reader, Type objectType, HashSet<int> existingValue, bool hasExistingValue, JsonSerializer serializer){return existingValue;}public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer){writer.WriteNull();}}

就是这么简单,然后就可以在 SerializeObject 的时候指定下自定义的 HashSetConverter 即可,然后再将程序跑起来看一下。

var json = JsonConvert.SerializeObject(algorithModel, Formatting.Indented, new HashSetConverter());

从图中看,貌似也是解决了,但我突然发现自己要钻牛角尖了,如果我的实体中又来了一个顶级优质客户群的 TopNCustomerIDHash,但因为这个CustomerID 比较少,我希望在 Json 中能保留下来,然后就是踢掉的那个 CustomerIDHash 我要保留 CustomerIDHash.Length,哈哈,搞事情哈,那接下来怎么解决呢?

  • 修改 Model 实体

class CustomerAlgorithmModel{public HashSet<int> CustomerIDHash { get; set; }// topN 优质客户群public HashSet<int> TopNCustomerIDHash { get; set; }}
  • HashSetConverter 增加逻辑鉴别是否为保留字段

public override void WriteJson(JsonWriter writer, HashSet<int> value, JsonSerializer serializer){if (writer.Path == "TopNCustomerIDHash"){writer.WriteStartArray();foreach (var item in value){writer.WriteValue(item);}writer.WriteEndArray();}else{writer.WriteValue(value.Count);}}
  • 最后给 TopNCustomerIDHash 赋值

var algorithModel = new CustomerAlgorithmModel(){CustomerType = 1,DisplayName = "????????",Report = new ReprotModel(){TotalCustomerCount = 1000,TotalTradeCount = 50},CustomerIDHash = new HashSet<int>(Enumerable.Range(1, 500000)),TopNCustomerIDHash = new HashSet<int>(Enumerable.Range(1, 10)),};

三块都搞定后就可以把程序跑起来了,如下图:

貌似钻牛角尖的问题是解决了,既然钻牛角尖肯定要各种鄙视,比如这里的 ReportModel 我是不需要的,CustomerType 我也是不需要的,我仅仅需要看一下 DisplayName 和 TotalCustomerCount 这两个字段就可以了, 那这个要怎么解决呢?

3. 使用 匿名类型

确实很多时候记日志,就是为了跟踪 Model 中你特别关心的那几个字段,所以掺杂了多余的字段确实也是没必要的,这里可以用匿名来解决,我就来写一段代码:

var json = JsonConvert.SerializeObject(new{algorithModel.DisplayName,algorithModel.Report.TotalCustomerCount}, Formatting.Indented);

三:总结

虽然阻击了几个回合,但同时也发现了 Newtonsoft 中还有特别多的未挖掘功能,真的需要好好研究研究,源码已下好,接下来准备做个系列来解剖一下,值得一提的是 .Net中已自带了 System.Text.Json.JsonSerializer 类,目前来看功能还不算太丰富,简单用用还是可以的,本篇就说到这里,希望对您有帮助。

对 JsonConvert 的认识太肤浅了,终于还是遇到了问题相关推荐

  1. 华为云存储空间图库占比太大_终于知道为什么华为手机删了照片,存储空间还是不足了!...

    原标题:终于知道为什么华为手机删了照片,存储空间还是不足了! 不管是64GB还是128GB,手机用了一段时间之后,都会发现存储内存就不足了.手机存储内存不足,多数人都会优先考虑删除部分不用了的.或者是 ...

  2. 太好了, 终于梳理清楚Python多线程与多进程

    在学习Python的过程中,有接触到多线程编程相关的知识点,先前一直都没有彻底的搞明白.今天准备花一些时间,把里面的细节尽可能的梳理清楚. 线程与进程的区别 进程(process)和线程(thread ...

  3. 今天跟某个投了社区团购的资本合伙人聊,发现对于社区团购的认知,还是太肤浅

    我原本以为,互联网公司做社区团购,只是为了干掉卖菜小商贩,挣点批零差,今天聊完发现,我还是大意了. 干掉小商贩只是第一步,他们死掉之后,跟着死掉的就是现有的渠道供应体系,因为互联网公司会直接找品牌拿货 ...

  4. PMO只是PM的工具人?太肤浅了

    很多人对项目管理的职位理解可能仅仅停留在PM,但其实近几年来,PMO这个词儿越来越火. 之前老原也写过一篇:一个字母,10倍薪资,PMO项目经理到底强在哪?感兴趣的可以去回顾一下. 针对以上那篇,大家 ...

  5. Quercus 介绍: 这个TMD对我太用了,终于在JAVA和PHP找到平衡点了

    写道 Quercus是Caucho公司采用纯Java开发的一个PHP5引擎.基于开源授权协议GPL发布.Quercus自带很多个PHP模块和扩展如PDF,PDO,MySQL和JSON.可以利用这个引擎 ...

  6. 终于有人把各路StyleGAN做了个大汇总 | Reddit超热

    丰色 发自 凹非寺 量子位 报道 | 公众号 QbitAI StyleGAN在各种图像处理和编辑任务上,表现很惊艳. 然而,"干一种活"就得换个体系重新"培训" ...

  7. 今天的我也不太清楚的即时通讯

    今天的我也不太清楚的即时通讯,就在外面裹了一层保护膜,看见这个牙签盒,静思躬行,有可读性,依旧在奋斗中找到快乐,因为里面原有很多牙签,下山时出现一条小道,宁老师写出了真情实感,此时. 用来干什么的即时 ...

  8. [转]终于有人说出来了——Java不适合于作为主要编程教学语言

    CSDN首页推荐了一篇文章,说两位退休的美国大学教授上书反对将Java作为编程教学语言,对此我表示高度认同.对于Java,我并不反感,而且相信它在工业应用中的地位不可取代,但是,我一直反对将Java作 ...

  9. 1.1 《硬啃设计模式》 第1章 大话设计模式

    设计模式不是一般的难! 第一难:需要你有真正的OO水平,有大量的编码及设计基础. 第二难:难以在工作中真正实践全部23中设计模式,无实践就无法真正理解.很少系统需要用到设计模式,或者只能用到很少的一部 ...

最新文章

  1. 金融风控--申请评分卡模型--特征工程(特征分箱,WOE编码) 标签: 金融特征分箱-WOE编码 2017-07-16 21:26 4086人阅读 评论(2) 收藏 举报 分类: 金融风
  2. CLion 远程Linux服务器 开发调试
  3. [转载] java中关于用\t格式输出
  4. 抖音直播APP软件系统为什么能这么火?反映出的问题又会是什么?
  5. Java_模拟comet的实现
  6. 农业灌溉泵行业调研报告 - 市场现状分析与发展前景预测
  7. androidpn的学习研究(二)androidpn-server服务端启动过程的理解分析
  8. 快速搭建企业级邮件系统iRedMail+Mysql+Postfix+php
  9. mysql做主从分离后插入更新过慢
  10. missing required library libmysql_e.dll,126 解决办法
  11. GIS空间分析之Buffer
  12. 全球与中国大麻化妆品市场深度研究分析报告
  13. python 控制手机摄像头_用Python获取摄像头并实时控制人脸 !
  14. SpringBoot自动装配原理浅析
  15. 哪些是常见的敏感异常Java_java敏感异常有哪些
  16. 【强大的视频编辑工具】Adobe Premiere Pro CC 2019 for Mac
  17. 转: 现代英军陆军军衔超低到高用英文怎么说
  18. 向日葵远程桌面提示连接断开解决方法
  19. 计算机网键怎么调出来,电脑输入法不见了怎么调出来?输入法快捷键是什么
  20. 如何动态生成pdf文件?

热门文章

  1. hdu_1728_逃离迷宫(bfs)
  2. 优秀程序员的 18 大法则【转载】
  3. Android开发最佳实践《IT蓝豹》
  4. c++ why can't class template hide its implementation in cpp file?
  5. 网络传输中的反码求和算法
  6. System.getProperty()参数
  7. ASP.NET GridView控件匯出EXCEL-移除控件,只是顯示文本
  8. 禁用内置键盘_如何禁用Windows 10的所有内置广告
  9. python学习笔记 --- 随机数进阶
  10. 长江存储年底提供自研32层堆叠3D NAND闪存样品