Newtonsoft.Json介绍
在做开发的时候,很多数据都是以Json格式传输的,而使用Json的时候,我们通常会涉及到几个序列化对象的使用:
- System.Runtime.Serialization.Json.DataContractJsonSerializer
- System.Web.Script.Serialization.JavaScriptSerializer
- Json.NET即Newtonsoft.Json
由于Json.NET的性能及通用性较好,因此它的使用范围越来越广,借助前人的经验今天我也总结使用一下。
官网API:http://www.newtonsoft.com/json/help/html/N_Newtonsoft_Json.htm
基本用法
Json.Net是支持序列化和反序列化DataTable、DataSet、Entity Framework和Entity的
private void Newtonsoft() { DataTable dt = new DataTable(); dt.Columns.Add("Name", Type.GetType("System.String")); dt.Columns.Add("Sex", Type.GetType("System.String")); dt.Columns.Add("Age", Type.GetType("System.Int32")); dt.Columns.Add("PhoneNumber", Type.GetType("System.String")); for (int i = 0; i < 3; i++) { DataRow dr = dt.NewRow(); dr["Name"] = "Name" + i; dr["Sex"] = i % 2 == 0 ? "女" : "男"; dr["Age"] = 18 + i; dr["PhoneNumber"] = ""; dt.Rows.Add(dr); } /*序列化DataTable*/ string json = JsonConvert.SerializeObject(dt); /*反序列化DataTable*/ DataTable dtSource = JsonConvert.DeserializeObject
(json)
; foreach (DataRow item
in dtSource
.Rows) { string name = item[
"Name"]
.ToString()
; string sex = item[
"Sex"]
.ToString()
; int age = int
.Parse(item[
"Age"]
.ToString())
; string phoneNumber = item[
"PhoneNumber"]
.ToString()
; } }
不创建新类型对json字符串反序列化
可以利用JObject 对象实现通过[]来读取对象中的属性的功能。
private void TestHttpHelper() { string url = "http://openapi.tencentyun.com/v3/user/get_info"; string data = "openid=BBA065E01CB73FFE96FA&" + "openkey=5F154D7D2751AEDCF290F70297B7EC&" + "appid=2&" + "sig=VrN%2BTn5J%2Fg4IIo0egUdxq6%2B0otk%3D&" + "pf=qzone&" + "format=json&" + "userip=112.90.139.30"; string result = HttpHelper.HttpGet(url + "?" + data); JObject obj = JsonConvert.DeserializeObject
(result);
int int1 = Convert.ToInt32(obj[
"ret"]);
string str1 = obj[
"msg"].ToString(); }
高级用法
- 忽略某些属性
- 默认值的处理
- 空值的处理
- 支持非公共成员
- 日期处理
- 自定义序列化的字段名称
- 动态决定属性是否序列化
| 参数 | 解释 |
|---|---|
| OptOut | 默认值,类中所有公共成员都会被序列化,如果不想被序列化,可以加特性JsonIgnore |
| OptIn | 默认情况下,所有成员都不会被序列化,类中的成员只有加特性Json Property才会被序列化,当类的成员很多,但客户端仅仅需要一部分数据时很有用 |
只有Name和PhoneNumber
[JsonObject(MemberSerialization.OptIn)] public class Person { [JsonProperty] public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string Address { get; set; } [JsonProperty] public string PhoneNumber { get; set; } }
不要性别、住址、手机号
[JsonObject(MemberSerialization.OptOut)] public class Person { public string Name { get; set; } [JsonIgnore] public string Sex { get; set; } public int Age { get; set; } [JsonIgnore] public string Address { get; set; } [JsonIgnore] public string PhoneNumber { get; set; } }
二、默认值处理
序列化时想忽略默认值属性可以通过JsonSerializerSettings.DefaultValueHanding来设置,该值为枚举值
| 参数 | 解释 |
|---|---|
| DefaultValueHanding.Ignore | 序列化和反序列化时,忽略没赋值的属性 |
| DefaultValueHanding.Include | 序列化和反序列化时,包含没赋值的属性 |
public class Person { public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string Address { get; set; } public string PhoneNumber { get; set; } }
public class Person { public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] public string Address { get; set; } public string PhoneNumber { get; set; } }
四、支持非公共成员
序列化时默认都是只处理公共成员,如果需要处理非公共成员,就要在该成员上加特性”JsonProperty”。
private不加JsonProperty:
public class Person { public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string Address { get; set; } public string PhoneNumber { get; set; } private int Wife { get; set; } public Person() { Wife = 3; } }
private加JsonProperty:
public class Person { public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string Address { get; set; } public string PhoneNumber { get; set; } [JsonProperty] private int Wife { get; set; } public Person() { Wife = 3; } }
五、日期处理
DateTime类型属性的处理稍微麻烦点,系统默认格式化为iso日期标准,
public class Person { public string Name { get; set; } public string Sex { get; set; } public DateTime Birthday { get; set; } }

public class Person { public string Name { get; set; } public string Sex { get; set; } [JsonConverter(typeof(IsoDateTimeConverter))] public DateTime Birthday { get; set; } }
但实际使用过程中大多数使用的可能是yyyy-MM-dd或yyyy-MM-dd HH:mm:ss这两种格式的日期,解决办法可以是将DateTime类型转成string类型自己先格式化然后再序列化。其次,Json.Net提供了IsoDateTimeConvert日期转换这个类,可以通过JsonConverter实现相应的日期转换,效果跟不加JsonConverter是一样的,在此就不截图了,但这明显不是我们想要的结果,我们可以继承该类实现自己的日期格式
public class Person { public string Name { get; set; } public string Sex { get; set; } [JsonConverter(typeof(ChinaDateTimeConcerter))] public DateTime Birthday { get; set; } } public class ChinaDateTimeConcerter : DateTimeConverterBase { private static IsoDateTimeConverter dtConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd" }; public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return dtConverter.ReadJson(reader, objectType, existingValue, serializer); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { dtConverter.WriteJson(writer, value, serializer); } }
这样自己就实现了一个yyyy-MM-dd日期格式化转换类,如果需要yyyy-MM-dd HH:mm:ss日期格式自己也可以很容易实现了。
六、自定义序列化字段的名称
实体类中定义的属性名可能不是自己想要的名称,但是不能更改实体定义,这个时候可以自定义序列化字段的名称。
public class Person { public string Name { get; set; } [JsonProperty(PropertyName = "MySex")] public string Sex { get; set; } [JsonProperty(PropertyName = "MyAge")] public int Age { get; set; } }
public class Person { public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } public string Address { get; set; } public string PhoneNumber { get; set; } } public class LimitPropsContractResolver : DefaultContractResolver { string[] props = null; public LimitPropsContractResolver(string[] props) { //指定要序列化属性的清单 this.props = props; } protected override IList
CreateProperties(Type type, MemberSerialization memberSerialization) { IList
list =
base.CreateProperties(type, memberSerialization);
//只保留清单列出的属性
return list.Where(p => props.Contains(p.PropertyName)).ToList(); } }
总结
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/228026.html原文链接:https://javaforall.net
