Newtonsoft.Json 的基本用法
Ø 前言
说起 C# 对 JSON 的操作(序列化与反序列化),大家都会想到 JavaScriptSerializer、DataContractJsonSerializer 与 Newtonsoft.Json 等。三者都是用于操作 JSON 的框架利器,它们又有什么区别呢?本文包括:
1. 常用 JSON 操作框架(JavaScriptSerializer、DataContractJsonSerializer、Newtonsoft.Json)的区别与比较
2. 简单序列化与反序列化
3. 匿名对象
4. DataTable
5. 私有成员
6. 指定成员名称
7. 指定序列化成员
8. 枚举类型成员
1. 常用 JSON 操作框架(JavaScriptSerializer、DataContractJsonSerializer、Newtonsoft.Json)的区别与比较
1) 区别如下:
1. JavaScriptSerializer,位于 System.Web.Extensions.dll 程序集,它是 .NET 自带的程序集,适用于 Web 项目中,因为每当新建一个 Web 项目后,VS 都会自动帮我引用该程序集,
2. DataContractJsonSerializer,位于 System.Runtime.Serialization.dll 程序集,也是属于 .NET 自带的程序集。适用于 WCF 项目中,因为每当新建一个 WCF 项目后,VS 都会自动帮我引用该程序集。另外,由名称可见它是一种“数据契约 JSON 序列化”。
3. Newtonsoft.Json,一个第三方的开源类库,主要处理数据的 JSON 序列化操作,在性能或功能方面与前两者相比都有优势,官网:https://www.newtonsoft.com/json,适用于对 JSON 数据操作平凡的各种项目中。
2) 性能比较
1. 下图是 Newtonsoft.Json 官网给出的执行耗时比较

2. Newtonsoft.Json 官网当然说自己的牛逼,所以,本人在本机进行了代码验证,代码如下:
string jssStr, dcjsStr, jcStr;
Person[] jssArr, dcjsArr, jcArr;
int count = 100000;
Person[] persons = new Person[count];
for (int i = 0; i < count; i++)
{
persons[i] = new Person()
{
Name = string.Format("李三毛_{0}", i),
Age = 29,
Sex = true,
Address = "湖北省利川市",
Spouse = new Person()
{
Name = string.Format("大美妞_{0}", i),
Age = 25,
Sex = false,
Address = "湖北省利川市",
Spouse = null
}
};
}
System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();
//3.1 JavaScriptSerializer
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.MaxJsonLength = 92097152; //默认为:2097152
stopwatch.Restart();
jssStr = jss.Serialize(persons);
stopwatch.Stop();
Console.WriteLine("JavaScriptSerializer Serialize Time【{0:F1}s,{1}ms】,String Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, jssStr.Length);
stopwatch.Restart();
jssArr = jss.Deserialize<Person[]>(jssStr);
stopwatch.Stop();
Console.WriteLine("JavaScriptSerializer Deserialize Time【{0:F1}s,{1}ms】,Array Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, jssArr.Length);
//3.2 DataContractJsonSerializer
DataContractJsonSerializer dcjs = new DataContractJsonSerializer(typeof(Person[]));
stopwatch.Restart();
using (MemoryStream stream = new MemoryStream())
{
dcjs.WriteObject(stream, persons);
dcjsStr = Encoding.UTF8.GetString(stream.ToArray());
}
stopwatch.Stop();
Console.WriteLine("DataContractJsonSerializer Serialize Time【{0:F1}s,{1}ms】,String Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, dcjsStr.Length);
stopwatch.Restart();
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(dcjsStr)))
{
dcjsArr = dcjs.ReadObject(stream) as Person[];
}
stopwatch.Stop();
Console.WriteLine("DataContractJsonSerializer Deserialize Time【{0:F1}s,{1}ms】,Array Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, dcjsArr.Length);
//3.3 Newtonsoft.Json
stopwatch.Restart();
jcStr = JsonConvert.SerializeObject(persons);
stopwatch.Stop();
Console.WriteLine("Newtonsoft.Json Serialize Time【{0:F1}s,{1}ms】,String Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, jcStr.Length);
stopwatch.Restart();
jcArr = JsonConvert.DeserializeObject<Person[]>(jcStr);
stopwatch.Stop();
Console.WriteLine("Newtonsoft.Json Deserialize Time【{0:F1}s,{1}ms】,Array Length:{2}",
TimeSpan.FromMilliseconds(stopwatch.ElapsedMilliseconds).TotalSeconds, stopwatch.ElapsedMilliseconds, jcArr.Length);
Ø 运行结果(三者分别运行三次后的最短耗时)
1. Serialize(序列化)
1) DataContractJsonSerializer Serialize Time【0.7s,696ms】,String Length:14377781
2) Newtonsoft.Json Serialize Time【1.7s,1741ms】,String Length:14377781
3) JavaScriptSerializer Serialize Time【6.2s,6189ms】,String Length:14377781
2. Deserialize(反序列化)
1) DataContractJsonSerializer Deserialize Time【2.0s,2037ms】,Array Length:100000
2) Newtonsoft.Json Deserialize Time【2.4s,2407ms】,Array Length:100000
3) JavaScriptSerializer Deserialize Time【3.7s,3733ms】,Array Length:100000
Ø 可见,耗时最短的并不是 Newtonsoft.Json,而是 .NET 自带的 DataContractJsonSerializer,最差的是 JavaScriptSerializer,序列化用了6秒,而 DataContractJsonSerializer 则之需要1秒时间不到。所以这一局,DataContractJsonSerializer 胜出,而 Newtonsoft.Json 则稍微靠后,由于它的功能方面比较强大,所以还是继续研究它。
Ø 首先,我们定义一个测试的类,并创建类的实例和一个匿名对象(后面的示例基本都使用该类)
1. 定义测试类(Goods 为一个部分类)
/// <summary>
/// 商品
/// </summary>
public partial class Goods
{
/// <summary>
/// 商品Id
/// </summary>
public int GoodsId { get; set; }
/// <summary>
/// 商品名称
/// </summary>
public string GoodsName { get; set; }
/// <summary>
/// 价格
/// </summary>
public decimal Price { get; set; }
/// <summary>
/// 是否限购
/// </summary>
public bool IsQuota { get; set; }
/// <summary>
/// 商品属性数组
/// </summary>
public Attribute[] Attributes { get; set; }
/// <summary>
/// 商品属性
/// </summary>
public class Attribute
{
public string Name { get; set; }
public string Value { get; set; }
}
}
2. 创建类的实例
Goods[] goods = new Goods[]
{
new Goods()
{
GoodsId = 1,
GoodsName = "联想ThinkPad无线鼠标",
Price = 125.00m,
IsQuota = true,
Attributes = new Goods.Attribute[]
{
new Goods.Attribute() { Name = "品牌", Value = "Lenovo/联想" },
new Goods.Attribute() { Name = "颜色", Value = "黑色" }
}
}
};
var anonymousGoods = new[]
{
new
{
GoodsId = 2,
GoodsName = "联想ThinkPad无线键盘",
Price = 286.00m,
IsQuota = false,
Attributes = new []
{
new { Name = "品牌", Value = "Lenovo/联想" },
new { Name = "颜色", Value = "白色" }
}
}
};
2. 简单序列化与反序列化
1) 序列化
序列化通常使用 JsonConvert 类的 SerializeObject 方法,该方法有 6 个重载方法,例如:
string jsonStr1_1 = JsonConvert.SerializeObject(goods);
结果:
[{"GoodsId":1,"GoodsName":"联想ThinkPad无线鼠标","Price":125.00,"IsQuota":true,"Attributes":[{"Name":"品牌","Value":"Lenovo/联想"},{"Name":"颜色","Value":"黑色"}]}]
2) 反序列化
序列化通常使用 JsonConvert 类的 DeserializeObject 方法,该方法有 8 个重载方法,例如:
Goods[] jsonObj1_1 = JsonConvert.DeserializeObject<Goods[]>(jsonStr1_1);
结果:

3. 匿名对象
1) 序列化
string jsonStr1_2 = JsonConvert.SerializeObject(anonymousGoods);
结果:
[{"GoodsId":2,"GoodsName":"联想ThinkPad无线键盘","Price":286.00,"IsQuota":false,"Attributes":[{"Name":"品牌","Value":"Lenovo/联想"},{"Name":"颜色","Value":"白色"}]}]
2) 反序列化
var jsonObj1_2 = JsonConvert.DeserializeAnonymousType(jsonStr1_2, anonymousGoods);
结果:

4. DataTable
首先,创建一个 DataTable 对象并插入数据
DataTable dataTable = new DataTable();
dataTable.Columns.AddRange(new DataColumn[]
{
new DataColumn() { ColumnName = "GoodsId", DataType = typeof(int) },
new DataColumn() { ColumnName = "GoodsName", DataType = typeof(string) },
new DataColumn() { ColumnName = "Price", DataType = typeof(decimal) }
});
for (int i = 0; i < 2; i++)
{
DataRow dataRow = dataTable.NewRow();
dataRow["GoodsId"] = i + 1;
dataRow["GoodsName"] = string.Format("测试商品{0}", i + 1);
dataRow["Price"] = i + 101;
dataTable.Rows.Add(dataRow);
}
1) 序列化
string jsonStr3_1 = JsonConvert.SerializeObject(dataTable);
结果:[{"GoodsId":1,"GoodsName":"测试商品1","Price":101.0},{"GoodsId":2,"GoodsName":"测试商品2","Price":102.0}]
2) 反序列化
DataTable jsonObj3_1 = JsonConvert.DeserializeObject<DataTable>(jsonStr3_1);
结果:

5. 私有成员(以 Price、IsQuota 为例)
Newtonsoft.Json 默认是不处理 private(私有)成员的,如非要处理也是可以的,在私有成员上标记 JsonPropertyAttribute 特性即可,例如(修改 Goods):
private decimal _price = 126;
/// <summary>
/// 价格
/// </summary>
private decimal Price { get { return _price; } set { _price = value; } }
private bool _isQuota = true;
/// <summary>
/// 是否限购
/// </summary>
[JsonProperty]
private bool IsQuota { get { return _isQuota; } set { _isQuota = value; } }
1) 序列化
string jsonStr4_1 = JsonConvert.SerializeObject(goods);
结果:
[{"GoodsId":1,"GoodsName":"联想ThinkPad无线鼠标","IsQuota":true,"Attributes":[{"Name":"品牌","Value":"Lenovo/联想"},{"Name":"颜色","Value":"黑色"}]}]
2) 反序列化
Goods[] jsonObj4_1 = JsonConvert.DeserializeObject<Goods[]>(jsonStr4_1);
结果:

6. 指定成员名称
使用 JsonPropertyAttribute 特性的 PropertyName 属性指定 JSON 成员名称,例如(修改 Goods):
[JsonProperty("att_name")]
public string Name { get; set; }
[JsonProperty("att_val")]
public string Value { get; set; }
1) 序列化
string jsonStr5_1 = JsonConvert.SerializeObject(goods);
结果:
[{"GoodsId":1,"GoodsName":"联想ThinkPad无线鼠标","IsQuota":true,"Attributes":[{"att_name":"品牌","att_val":"Lenovo/联想"},{"att_name":"颜色","att_val":"黑色"}]}]
2) 反序列化
Goods[] jsonObj5_1 = JsonConvert.DeserializeObject<Goods[]>(jsonStr5_1);
结果:

7. 指定序列化成员
Newtonsoft.Json 提供三种序列化模式,使用 Newtonsoft.Json.MemberSerialization 枚举表示。例如(修改 Goods):
[JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]
public class Goods {...}
/// <summary>
/// 商品名称
/// </summary>
[JsonProperty]
public string GoodsName { get; set; }
|
OptOut |
默认值,序列化所有共有成员,可以使用 JsonIgnore 特性,标记不需要序列化的成员。 |
|
OptIn |
只序列化标记 JsonProperty 特性的成员。 |
|
Fields |
只序列化字段成员。注意:默认情况下字段也支持序列化和反序列化。 |
1) 序列化
string jsonStr6_1 = JsonConvert.SerializeObject(goods);
结果:[{"GoodsName":"联想ThinkPad无线鼠标","IsQuota":true}]
2) 反序列化
Goods[] jsonObj6_1 = JsonConvert.DeserializeObject<Goods[]>(jsonStr6_1);
结果:

8. 枚举类型成员
枚举类型成员默认情况下,是序列化枚举类型的值。如果希望序列化成员名称,需要在成员上标记 JsonConverter 特性,并指定 Newtonsoft.Json.Converters.StringEnumConverter 类型,例如(修改 Goods):
/// <summary>
/// 商品状态
/// </summary>
public enum Status
{
/// <summary>
/// 无
/// </summary>
None = 0,
/// <summary>
/// 上架
/// </summary>
Online = 1,
/// <summary>
/// 下架
/// </summary>
Offline = 2
}
/// <summary>
/// 商品扩展
/// </summary>
public partial class Goods
{
/// <summary>
/// 商品状态
/// </summary>
[JsonProperty]
[JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public Status Status { get; set; }
}
1) 序列化
string jsonStr7_1 = JsonConvert.SerializeObject(goods);
结果:[{"GoodsName":"联想ThinkPad无线鼠标","IsQuota":true,"Status":"Online"}]
2) 反序列化
Goods[] jsonObj7_1 = JsonConvert.DeserializeObject<Goods[]>(jsonStr7_1);
结果:

Newtonsoft.Json 的基本用法的更多相关文章
- 记录Newtonsoft.Json的日常用法
最近在做一个使用基于.net mvc 实现前后台传输Json的实例.网上找了一些资料.发现在开发的时候,许多的数据交互都是以Json格式传输的.其中涉及序列化对象的使用的有DataContractJs ...
- Newtonsoft.Json 的高级用法
Ø 简介 接着前一篇http://www.cnblogs.com/abeam/p/8295765.html,继续研究 Newtonsoft.Json 的一些高级用法.主要包括: 1. JSON ...
- Newtonsoft.Json 的解析用法。
JsonView是查看和分析json的利器,目录下的Newtonsoft.Json.dll ,我们可以当第三方引用之. >>> //想服务器端发送请求,获取订单信息 myReques ...
- 记一次 Newtonsoft.Json 巧妙的用法(C#)
数据添加的功能 有一个表格提交数据如下: 是否选择和文本值.分开保存到数据库太麻烦.取得时候也麻烦 想到了存成json数据.一个字段就可以了. html代码: <table class=&quo ...
- Newtonsoft.Json高级用法(转)
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- 【转】 Newtonsoft.Json高级用法
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的字段名称
手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多次修改中,实体添加了很多字段用于中间计算或者存储,然后最终用Newtonsoft.Json进行序列化返回数 ...
- 转:Newtonsoft.Json高级用法
原文地址:http://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口多 ...
- Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...
随机推荐
- 如何用MarsEdit快速插入源代码
开始用MarsEdit来写博文,客户端的,毕竟是要方便的多啊. 遇到的第一个问题就是:MarsEdit没有提供快速插入源代码的工具,而对于我这枚码农而言,这个就有点太杯具了. 简单研究了一下,发现Ma ...
- a超链接设置样式
/* divcss5对象内 a超链接设置样式 */ .divcss5 a:link{ color:#F00}/* 链接默认为红色 */ .divcss5 a:hover{ color:#000}/* ...
- poj1637 Sightseeing tour(混合图欧拉回路)
题目链接 题意 给出一个混合图(有无向边,也有有向边),问能否通过确定无向边的方向,使得该图形成欧拉回路. 思路 这是一道混合图欧拉回路的模板题. 一张图要满足有欧拉回路,必须满足每个点的度数为偶数. ...
- 利用selenium并使用gevent爬取动态网页数据
首先要下载相应的库 gevent协程库:pip install gevent selenium模拟浏览器访问库:pip install selenium selenium库相应驱动配置 https: ...
- '新', '泽' - ImageMagick - UTF-8非最短形式及编码安全问题
最近偶然发现,把软件放到 [新建文件夹] 中,ImageMagick 竟无法正常的加载图片了. 我去!什么情况? 抛出的错误是找不到相关的dll,软件中已对中文进行了utf-8编码,这几年来一直没发 ...
- JMeter请求执行次数 你想执行几次就执行几次
今天介绍下JMeter如何控制请求执行次数 主要有两种方式: 方式一:通过循环控制器控制每个请求的执行次数 例如:脚本执行规律是这样的,login-->customerPage-->sea ...
- Python之推导式、生成器表达式
l = [i for i in range(10)] print(l) l1 = ['选项%s'%i for i in range(10)] print(l1) 1.把列表解析的[]换成()得到的就是 ...
- 斯坦福大学公开课机器学习: advice for applying machine learning | regularization and bais/variance(机器学习中方差和偏差如何相互影响、以及和算法的正则化之间的相互关系)
算法正则化可以有效地防止过拟合, 但正则化跟算法的偏差和方差又有什么关系呢?下面主要讨论一下方差和偏差两者之间是如何相互影响的.以及和算法的正则化之间的相互关系 假如我们要对高阶的多项式进行拟合,为了 ...
- TestNg 12. extentReport测试报告
直接上代码:以下是我的目录结构,首先新建一个包名字叫 com.tester.extent.demo,直接新建两个类就可以,名字叫 ExtentTestNGIReporterListener 和 T ...
- UltraCompare文件内容比较工具
http://www.52pojie.cn/thread-541895-1-1.html 云盘里有<ignore_js_op> <ignore_js_op> UltraComp ...