一:讲故事

上一篇介绍的 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 六个超简单又实用的特性,值得一试 【下篇】相关推荐

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

    一:讲故事 看完官方文档,阅读了一些 Newtonsoft 源码,对它有了新的认识,先总结 六个超经典又实用的特性,同大家一起分享,废话不多说,快来一起看看吧~~~ 二:特性分析 1. 代码格式化 如 ...

  2. java最美验证码_java超简单,超级实用验证码

    java超简单,超级实用验证码 1.   验证码(2) dsnaValidateCode.jar dsnaValidateCode_src.rar ValidateCode.java 验证码生成类 J ...

  3. vm服务器共享文件夹,超简单与实用的两种vmware虚拟机与主机共享文件的方法 | 古意人...

    相信很多朋友都使用vmware这款虚拟机软件,古意人主要用虚拟机来测试一些大型的.使用频次低的软件,此外偶尔用来运行一些来路不明的程序,以免主机系统中毒,vmware虚拟系统可谓之利器,古意人建议主机 ...

  4. 图片大小怎么改小?两个超简单的方法教给大家

    在我们平时的工作当中,经常会需要上传图片素材,但是不知道大家有没有遇到过图片太大不允许上传的情况,这时我们应该怎么办呢?这种情况下我们应该压缩图片大小,让图片符合上传条件就可以了,有很多小伙伴可能不清 ...

  5. 3款强大且实用的电脑软件,颠覆你的认知,值得一试

    闲话少说,直上狠货. 1.一个木函 一个木函仅一张照片的体积,却提供了与日常.图片.设备.文件.文字处理等等相关的80多种工具,相当实用,更牛的是,完全免费,无任何弹屏广告. 一个木函体积小,简明纯粹 ...

  6. 用python建云盘_实用的Python(3)超简单!基于Python搭建个人“云盘”

    1 简介 当我们想要从本地向云服务器上传文件时,比较常用的有pscp等工具,但避免不了每次上传都要写若干重复的代码,而笔者最近发现的一个基于Python的工具updog,可以帮助我们在服务器上搭建类似 ...

  7. 微信公众平台之超简单实用的天气预报后台实现

    微信公众平台之超简单实用的天气预报后台实现 概述,前段时间我在开发一个自己的微信公众平台,需要实现天气预报功能,在网上度娘了下,实现天气预报的接口API还蛮多的,有:中国气象局.雅虎和新浪等,中国天气 ...

  8. 录屏工具下载哪个好?分享:超简单的录屏工具及实用方法

    在短视频盛行,知识付费,粉丝经济的背景下,下载一款好用的录屏工具可以如虎添翼,为自己制作视频助力.然而面对各种各样的录屏工具,很多人不知道下载哪个好.一旦录屏工具没有选对,即使下载了,不会用也没有意义 ...

  9. 面试Python开发的这道题超简单,我却搞砸了!

    题图 | Shutterstock / studiostoks 这道算法题明明超简单-- 上午10点,在T公司的会议室里,小R正在参加一场他准备了好几天的技术面试. 整体来说,他在这场面试中的表现还不 ...

最新文章

  1. 苹果又魔改安卓? iOS 15 正式发布、可跨设备移动文件,这届 WWDC21 带来了什么?...
  2. 将HTML5 Canvas的内容保存为图片
  3. vue中将md转成html,Vue/Vue中Html和Markdown互相转换/README.md · 倚栏听风/LearningNotes - Gitee.com...
  4. 经常使用Log日志打印输出
  5. 达梦数据库导入oracle数据_达梦数据库助力加速石油石化行业数字化转型升级
  6. java语言程序设计基础篇14.6答案_《Java语言程序设计-基础篇》答案-第15章
  7. Android之蓝牙开发浅析
  8. 【kafka】Kafka 之 Group 状态变化分析及 Rebalance 过程
  9. 分治算法——快速排序
  10. proxy_cache的使用
  11. 【STL源码剖析读书笔记】自己实现stack之MyStack(底层用MyList)
  12. ARM中的RO、RW和ZI DATA说明
  13. android直到开机动画播放完,Android手机开机动画的修改
  14. Android半透明
  15. 190320运算符数据类型
  16. C#图片处理:生成大尺寸图片,以边框颜色填充
  17. Python(10)--文件读写/模块制作与发布
  18. iOS 新特性实现 3DTouch 开发
  19. 如何在Excel中将多个单元格中的文本合并到一个单元格中
  20. 数据库DDL与DML指的什么?

热门文章

  1. tomcat学习笔记(JDK+TOMCAT+AXIS)
  2. 找call写call_如何将Google Call Widget添加到任何网页
  3. Mysql+Navicat for Mysql
  4. 排序算法之快速排序详解
  5. javascript权威指南--学习笔记
  6. 删除Linux下/tmp目录引起的不正常登录系统
  7. ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
  8. phpmyadmin的安装部署
  9. ln -s 的一个坑
  10. JavaScript中的arguments,callee,caller