一:讲故事

看完官方文档,阅读了一些 Newtonsoft 源码,对它有了新的认识,先总结 六个超经典又实用的特性,同大家一起分享,废话不多说,快来一起看看吧~~~

二:特性分析

1. 代码格式化

如果你直接使用 JsonConvert.SerializeObject的话,默认情况下所有的json是挤压在一块的,特别不方便阅读,如下所示:


  1. static void Main(string[] args)
  2. {
  3. var reportModel = new ReportModel()
  4. {
  5. ProductName = "法式小众设计感长裙气质显瘦纯白色仙女连衣裙",
  6. TotalPayment = 100,
  7. TotalCustomerCount = 2,
  8. TotalProductCount = 333
  9. };
  10. var json = JsonConvert.SerializeObject(reportModel);
  11. System.Console.WriteLine(json);
  12. }
  13. }
  14. public class ReportModel
  15. {
  16. public string ProductName { get; set; }
  17. public int TotalCustomerCount { get; set; }
  18. public decimal TotalPayment { get; set; }
  19. public int TotalProductCount { get; set; }
  20. }

那怎么办呢? JsonConvert中提供了一个 Formatting.Indented 用来格式化json,这样在 debug 的过程中就非常友好,改造如下:

2. 踢掉没有被赋值的字段

如果你写过给 App 提供数据的后端服务,我相信你对手机流量这个词特别敏感,往往一个 Model 上有十几个字段,但需要传给 App 可能就 三四个字段,这就造成了巨大的流量浪费,如下图:


  1. static void Main(string[] args)
  2. {
  3. var reportModel = new ReportModel()
  4. {
  5. ProductName = "法式小众设计感长裙气质显瘦纯白色仙女连衣裙",
  6. TotalPayment = 100
  7. };
  8. var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented);
  9. System.Console.WriteLine(json);
  10. }

从图中可以看到,TotalCustomerCountTotalProductCount 这两个字段就没必要了,Netnewsoft 中提供了 DefaultValueHandling.Ignore 剔除默认值的枚举,太实用了,改造如下:


  1. var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
  2. new JsonSerializerSettings
  3. {
  4. DefaultValueHandling = DefaultValueHandling.Ignore
  5. });

3. 兼容其他语言的 驼峰,蛇形命名法

每一套编程语言都有各自偏好的命名法,比如 js 中都喜欢采用 驼峰命名法,在 mysql 中我见过最多的 蛇形命名法,而我们在 C# 中序列化的属性一般都是大写字母开头,比如你看到的 特性二 中的字段,那这里就存在问题了,有没有办法兼容一下,给 js 就用 驼峰,给 mysql 就用 蛇形,这样显得对别人友好一些,不是嘛,接下来看看怎么改造。

  • 驼峰命名 CamelCasePropertyNamesContractResolver

  1. var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
  2. new JsonSerializerSettings
  3. {
  4. ContractResolver = new CamelCasePropertyNamesContractResolver()
  5. });

  • 蛇形命名 SnakeCaseNamingStrategy

  1. var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented,
  2. new JsonSerializerSettings
  3. {
  4. ContractResolver = new DefaultContractResolver()
  5. {
  6. NamingStrategy = new SnakeCaseNamingStrategy()
  7. }
  8. });

4. 自定义属性的名字

如果你和第三方系统进行过对接开发,通常都会遇到这个问题,就拿 OpenTaobao 来说,我的Model总不能按照它文档这样定义吧,而且字段名称也不可能做到完全一致,如下图:

所以这里面必然要存在一个 Mapping 的过程,这就可以用 JsonProperty -> propertyName 帮你搞定,为了方便演示,我还是用 reportModel 吧。


  1. static void Main(string[] args)
  2. {
  3. var json = "{'title':'法式小众设计感长裙气质显瘦纯白色仙女连衣裙','customercount':1000,'totalpayment':100.0,'productcount':10000}";
  4. var reportModel = JsonConvert.DeserializeObject<ReportModel>(json);
  5. }
  6. public class ReportModel
  7. {
  8. [JsonProperty("title")] public string ProductName { get; set; }
  9. [JsonProperty("customercount")] public int TotalCustomerCount { get; set; }
  10. [JsonProperty("totalpayment")] public decimal TotalPayment { get; set; }
  11. [JsonProperty("productcount")] public int TotalProductCount { get; set; }
  12. }

5. 对字段的 正向剔除 和 反向剔除

可能有些朋友对这两个概念不是特别了解,这里我仅显示 Model 中的 ProductName 为例讲解一下:

  • 正向剔除: 默认所有都显示,手工踢掉不显示的,使用 MemberSerialization.OptOut 配合 JsonIgnore

  1. static void Main(string[] args)
  2. {
  3. var reportModel = new ReportModel()
  4. {
  5. ProductName = "法式小众设计感长裙气质显瘦纯白色仙女连衣裙",
  6. TotalPayment = 100
  7. };
  8. var json = JsonConvert.SerializeObject(reportModel, Formatting.Indented);
  9. System.Console.WriteLine(json);
  10. }
  11. [JsonObject(MemberSerialization.OptOut)]
  12. public class ReportModel
  13. {
  14. public string ProductName { get; set; }
  15. [JsonIgnore] public int TotalCustomerCount { get; set; }
  16. [JsonIgnore] public decimal TotalPayment { get; set; }
  17. [JsonIgnore] public int TotalProductCount { get; set; }
  18. }

  • 反向剔除: 默认都不显示,手工指定要显示的,使用 MemberSerialization.OptIn 配合 JsonProperty

  1. [JsonObject(MemberSerialization.OptIn)]
  2. public class ReportModel
  3. {
  4. [JsonProperty] public string ProductName { get; set; }
  5. public int TotalCustomerCount { get; set; }
  6. public decimal TotalPayment { get; set; }
  7. public int TotalProductCount { get; set; }
  8. }

6. 多个json 合并到 一个Model

这个特性当初打破了我对 Newtonsoft 的认知观,不知道您呢? 通常我们都会认为 一个 json 对应一个 model,一个 model 对应一个 json,居然还可以多个 json 对应一个 model 的情况,这就有意思了,场景大家可以自己想一想哈,这里使用 PopulateObject 方法就可以轻松帮你搞定,接下来看看怎么写这个代码:


  1. static void Main(string[] args)
  2. {
  3. var json1 = "{'ProductName':'法式小众设计感长裙气质显瘦纯白色仙女连衣裙'}";
  4. var json2 = "{'TotalCustomerCount':1000,'TotalPayment':100.0,'TotalProductCount':10000}";
  5. var reportModel = new ReportModel();
  6. JsonConvert.PopulateObject(json1, reportModel);
  7. JsonConvert.PopulateObject(json2, reportModel);
  8. }

是不是有点意思

三:总结

为了怕影响阅读体验,这一篇就先总结六个供大家欣赏,Newtonsoft 这玩意确实非常强大,太多的东西需要去挖掘,希望本篇对你有帮助,谢谢。

Newtonsoft 六个超简单又实用的特性,值得一试 【上篇】的更多相关文章

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

    一:讲故事 上一篇介绍的 6 个特性从园子里的反馈来看效果不错,那这一篇就再带来 6 个特性同大家一起欣赏. 二:特性分析 1. 像弱类型语言一样解析 json 大家都知道弱类型的语言有很多,如: n ...

  2. ASP.NET中一种超简单的Ajax解决方案

    为什么是Ajax2? 因为之前有一个blqw.Ajax,并且已经在项目中投入使用了,但是没有这个方便,这个是后来才弄的,为了纪念第一版的blqw.Ajax,所以这个就2了... 话说看了评论才发现,原 ...

  3. 超简单的全新win10安装

    1.准备工作! 这里说一下需要装系统的东西: 至少8G的U盘或内存卡 一台Windows电脑 在要安装的电脑上至少有16G的空间,最好至少64G. 2.现成电脑下载文件(已经有重装系统U盘跳过这一步) ...

  4. 分享六个基于Bootstrap的实用开发教程和模板演示

    关于Bootstrap,相信大家一定不陌生,它已经成为现在主流产业的一个重要工具,Bootstrap提供了优雅的HTML和CSS规范,它基于jQuery框架开发的,它在jQuery框架的基础上进行了更 ...

  5. 【Android自己定义View实战】之自己定义超简单SearchView搜索框

    [Android自己定义View实战]之自己定义超简单SearchView搜索框 这篇文章是对之前文章的翻新,至于为什么我要又一次改动这篇文章?原因例如以下 1.有人举报我抄袭,原文链接:http:/ ...

  6. 【转载】手把手教你使用Git(简单,实用)

    手把手教你使用Git(简单,实用) 标签: git 2016年04月21日 20:51:45 1328人阅读 评论(0) 收藏 举报 一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. ...

  7. 超简单集成 HMS ML Kit 实现最大脸微笑抓拍

    前言 如果大家对 HMS ML Kit 人脸检测功能有所了解,相信已经动手调用我们提供的接口编写自己的 APP 啦.目前就有小伙伴在调用接口的过程中反馈,不太清楚 HMS ML Kit 文档中的 ML ...

  8. 把C#程序(含多个Dll)合并成一个Exe的超简单方法

    开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一个exe就能完美运行的小工具.那该怎么办呢? 下文介绍一种超 ...

  9. 记住密码超简单实现(C#)

    实现效果如下 实现过程 [Serializable] class User { //记住密码 private string loginID; public string LoginID { get { ...

随机推荐

  1. APP元素定位和操作

    webdriver 提供了八种元素定位方法: 在 Python 语言中对应的定位方法如下:find_element_by_id()find_element_by_name()find_element_ ...

  2. 《计算机网络》课程笔记 (Ch03-运输层)

    为运行在不同主机上的应用进程之间提供逻辑通信功能. 将应用层报文切分为块,然后加上运输层首部,形成报文段,交付给网络层. 多路复用与多路分解 将网络层提供的主机到主机交付服务延伸到进程到进程交付服务. ...

  3. mysql 数据类型笔记

    一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...

  4. zabbix通过IPMI监控服务器传感器参数

    一.需求:机房dell服务器和IBM服务器皆有主板管理接口iDRAC和iMM,上周已为服务器管理接口配置了ip地址,考虑通过zabbix实现对服务器传感器参数的实时监控.使用DELL-DL1300服务 ...

  5. ArcCore重构-打通Can各层ID配置

    https://mp.weixin.qq.com/s/JX7VZwyMqk_9iVMm_N2pxA https://mp.weixin.qq.com/s/5Y8Dt9j1-NQmnjfYhE19dg ...

  6. 数据库之 MySQL --- 数据处理 之 表操作、CRUD(六)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一. 表操作 创建数据库CREATE DATABASE demo-- 删除数据库DROP DATABAS ...

  7. Java实现 LeetCode 725 分隔链表(暴力)

    725. 分隔链表 给定一个头结点为 root 的链表, 编写一个函数以将链表分隔为 k 个连续的部分. 每部分的长度应该尽可能的相等: 任意两部分的长度差距不能超过 1,也就是说可能有些部分为 nu ...

  8. Java实现 LeetCode 502 IPO(LeetCode:我疯起来连自己都卖)

    502. IPO 假设 力扣(LeetCode)即将开始其 IPO.为了以更高的价格将股票卖给风险投资公司,力扣 希望在 IPO 之前开展一些项目以增加其资本. 由于资源有限,它只能在 IPO 之前完 ...

  9. Java实现 LeetCode 174 地下城游戏

    174. 地下城游戏 一些恶魔抓住了公主(P)并将她关在了地下城的右下角.地下城是由 M x N 个房间组成的二维网格.我们英勇的骑士(K)最初被安置在左上角的房间里,他必须穿过地下城并通过对抗恶魔来 ...

  10. java实现转方阵

    /* 对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 转置后变为: 1 5 9 13 2 6 ...