Newtonsoft.Json 的基本用法

摘要:
本文包括:1.常见JSON操作框架的区别和比较2.简单的序列化和反序列化3.匿名对象4.数据表5.私有成员6.指定成员名称7.指定序列化成员8.枚举类型成员1.常见JSON运算框架的区别与比较1)区别如下:1.JavaScript序列化器,位于System.Web.Extensions中。dll程序集是NET本机程序集,适用于Web项目,因为每当创建新的Web项目时,VS都会自动为我引用该程序集。2.DataContractJsonSerializer,位于System.Runtime.Serialization中。dll程序集,也是的本机程序集。NET。

Ø  前言

说起 C# JSON 的操作(序列化与反序列化),大家都会想到 JavaScriptSerializerDataContractJsonSerializer Newtonsoft.Json 等。三者都是用于操作 JSON 的框架利器,它们又有什么区别呢?本文包括:

1.   常用 JSON 操作框架(JavaScriptSerializerDataContractJsonSerializerNewtonsoft.Json)的区别与比较

2.   简单序列化与反序列化

3.   匿名对象

4.   DataTable

5.   私有成员

6.   指定成员名称

7.   指定序列化成员

8.   枚举类型成员

 

1.   常用 JSON 操作框架(JavaScriptSerializerDataContractJsonSerializerNewtonsoft.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 官网给出的执行耗时比较

clip_image002[1]

 

2.   Newtonsoft.Json 官网当然说自己的牛逼,所以,本人在本机进行了代码验证,代码如下:

string jssStr, dcjsStr, jcStr;

Person[] jssArr, dcjsArr, jcArr;

int count = 100000;

Person[] persons = newPerson[count];

for (int i = 0; i < count; i++)

{

    persons[i] = newPerson()

    {

        Name = string.Format("李三毛_{0}", i),

        Age = 29,

        Sex = true,

        Address = "湖北省利川市",

        Spouse = newPerson()

        {

            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 = newJavaScriptSerializer();

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 = newDataContractJsonSerializer(typeof(Person[]));

stopwatch.Restart();

using (MemoryStream stream = newMemoryStream())

{

    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 = newMemoryStream(Encoding.UTF8.GetBytes(dcjsStr)))

{

    dcjsArr = dcjs.ReadObject(stream) asPerson[];

}

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 Time0.7s,696ms】,String Length:14377781

2)   Newtonsoft.Json Serialize Time1.7s,1741ms】,String Length:14377781

3)   JavaScriptSerializer Serialize Time6.2s,6189ms】,String Length:14377781

2.   Deserialize(反序列化)

1)   DataContractJsonSerializer Deserialize Time2.0s,2037ms】,Array Length:100000

2)   Newtonsoft.Json Deserialize Time2.4s,2407ms】,Array Length:100000

3)   JavaScriptSerializer Deserialize Time3.7s,3733ms】,Array Length:100000

 

Ø  可见,耗时最短的并不是 Newtonsoft.Json,而是 .NET 自带的 DataContractJsonSerializer,最差的是 JavaScriptSerializer,序列化用了6秒,而 DataContractJsonSerializer 则之需要1秒时间不到。所以这一局,DataContractJsonSerializer 胜出,而 Newtonsoft.Json 则稍微靠后,由于它的功能方面比较强大,所以还是继续研究它。

 

Ø  首先,我们定义一个测试的类,并创建类的实例和一个匿名对象(后面的示例基本都使用该类)

1.   定义测试类(Goods 为一个部分类)

/// <summary>

///商品

///</summary>

publicpartial classGoods

{

    ///<summary>

    ///商品Id

    ///</summary>

    publicint GoodsId { get; set; }

 

    ///<summary>

    ///商品名称

    ///</summary>

    publicstring GoodsName { get; set; }

 

    ///<summary>

    ///价格

    ///</summary>

    publicdecimal Price { get; set; }

 

    ///<summary>

    ///是否限购

    ///</summary>

    publicbool IsQuota { get; set; }

 

    ///<summary>

    ///商品属性数组

    ///</summary>

    publicAttribute[] Attributes { get; set; }

 

    ///<summary>

    ///商品属性

    ///</summary>

    publicclassAttribute

    {

        publicstring Name { get; set; }

        publicstring Value { get; set; }

    }

}

 

2.   创建类的实例

Goods[] goods = newGoods[]

{

    newGoods()

    {

        GoodsId = 1,

        GoodsName = "联想ThinkPad无线鼠标",

        Price = 125.00m,

        IsQuota = true,

        Attributes = newGoods.Attribute[]

        {

            newGoods.Attribute() { Name = "品牌", Value = "Lenovo/联想" },

            newGoods.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);

结果:

clip_image003[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);

结果:

clip_image004[1]

 

4.   DataTable

首先,创建一个 DataTable 对象并插入数据

DataTable dataTable = newDataTable();

dataTable.Columns.AddRange(newDataColumn[]

{

    newDataColumn() { ColumnName = "GoodsId", DataType = typeof(int) },

    newDataColumn() { ColumnName = "GoodsName", DataType = typeof(string) },

    newDataColumn() { 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);

结果:

clip_image005[1]

 

5.   私有成员(以 PriceIsQuota为例

Newtonsoft.Json 默认是不处理 private(私有)成员的,如非要处理也是可以的,在私有成员上标记 JsonPropertyAttribute特性即可,例如(修改 Goods):

privatedecimal _price = 126;

///<summary>

///价格

///</summary>

privatedecimal Price { get { return _price; } set { _price = value; } }

 

privatebool _isQuota = true;

///<summary>

///是否限购

///</summary>

[JsonProperty]

privatebool 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);

结果:

clip_image006

 

6.   指定成员名称

使用 JsonPropertyAttribute特性的PropertyName属性指定 JSON 成员名称,例如(修改 Goods

[JsonProperty("att_name")]

publicstring Name { get; set; }

[JsonProperty("att_val")]

publicstring 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);

结果:

clip_image007

 

7.   指定序列化成员

Newtonsoft.Json 提供三种序列化模式,使用 Newtonsoft.Json.MemberSerialization枚举表示。例如(修改 Goods):

[JsonObject(Newtonsoft.Json.MemberSerialization.OptIn)]

publicclassGoods {...}

///<summary>

///商品名称

///</summary>

[JsonProperty]

publicstring 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);

结果:

clip_image008

 

8.   枚举类型成员

枚举类型成员默认情况下,是序列化枚举类型的值。如果希望序列化成员名称,需要在成员上标记 JsonConverter特性,并指定Newtonsoft.Json.Converters.StringEnumConverter类型,例如(修改 Goods):

///<summary>

///商品状态

///</summary>

publicenumStatus

{

    ///<summary>

    ///

    ///</summary>

    None = 0,

    ///<summary>

    ///上架

    ///</summary>

    Online = 1,

    ///<summary>

    ///下架

    ///</summary>

    Offline = 2

}

///<summary>

///商品扩展

///</summary>

publicpartialclassGoods

{

    ///<summary>

    ///商品状态

    ///</summary>

    [JsonProperty]

    [JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]

    publicStatus 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);

结果:

clip_image009

免责声明:文章转载自《Newtonsoft.Json 的基本用法》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Redis系列九 Redis集群Buffer Cache 原理下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Rxjava学习(二操作符)

操作符是为了解决对Observable对象的变换的问题,操作符用于在Observable和最终的Subscriber之间修改Observable发出的事件 1.filter   filter()操作符是可以对Observable流程的数据进行一层过滤处理,返回一个新的Observable,filter()返回为false的值将不会发出到Subscriber...

微信分享接口的java开发的一些小步骤

1.配置接口信息进行验证 代码如下:     /**     * 访问没认证的地址跳转     *     * @param request     * @return 登录页面     * @throws Exception     */    @RequestMapping(value = "/checkWxDomainUrl", method =...

Aviator

Aviator简介¶Aviator是一个高性能、轻量级的java语言实现的表达式求值引擎,主要用于各种表达式的动态求值。现在已经有很多开源可用的java表达式求值引擎,为什么还需要Avaitor呢? Aviator的设计目标是轻量级和高性能,相比于Groovy、JRuby的笨重,Aviator非常小,加上依赖包也才450K,不算依赖包的话只有70K;当然,...

poi解析office文档内容的工具类

第一步引入依赖 <!--xls--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId>...

spring+redis 集群下的操作

文章就是记录一下工作当中的用到的点,与测试方法以备用,会不断更新。 配置文件spring-redis.xml: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xs...

DevExpress WinForm MVVM数据和属性绑定指南(Part 1)

根据您绑定的属性,存在以下三种可能的情况: 常规绑定- ViewModel属性绑定到任何不可编辑的View元素属性。由于该元素不可编辑,因此您无需将更新通知发送回绑定属性(单向绑定)。 数据绑定- Model属性(数据字段)绑定到编辑器属性。如果用户可以更改编辑器值,则需要更新绑定属性(双向绑定)。 属性依赖- 来自同一个ViewModel的两个属性被绑...