Newtonsoft.Json高级用法
在做开发的时候,很多数据交换都是以json格式传输的。而使用Json的时候,我们很多时候会涉及到几个序列化对象的使用:DataContractJsonSerializer,JavaScriptSerializer 和 Json.NET即Newtonsoft.Json。大多数人都会选择性能以及通用性较好Json.NET,这个不是微软的类库,但是一个开源的世界级的Json操作类库,非常简单实用。 一.忽略某些属性 实体中有些属性不需要序列化返回,可以使用该特性。首先介绍Json.Net序列化的模式:OptOut 和 OptIn OptOut: 默认值,类中所有公有成员会被序列化,如果不想被序列化,可以用特性JsonIgnore OptIn : 默认情况下,所有的成员不会被序列化,类中的成员只有标有特性JsonProperty的才会被序列化,当类的成员很多,但客户端仅仅需要一部分数据时,很有用
//仅需要姓名属性 [JsonObject(MemberSerialization.OptIn)] public class Person { public int Age { get; set; } [JsonProperty] public string Name { get; set; } public string Sex { get; set; } public bool IsMarry { get; set; } public DateTime Birthday { get; set; } } //不需要是否结婚属性 [JsonObject(MemberSerialization.OptOut)] public class Person { public int Age { get; set; } public string Name { get; set; } public string Sex { get; set; } [JsonIgnore] public bool IsMarry { get; set; } public DateTime Birthday { get; set; } } //TEST代码: class Program { static void Main() { Person p = new Person(); p.Age = 10; p.Name = "ppl"; p.Sex = "MAN"; p.IsMarry = true; p.Birthday = DateTime.Now; string json = JsonConvert.SerializeObject(p); Console.WriteLine(json); Console.ReadKey(); } } 通过上面的例子可以看到,要实现不返回某些属性的需求很简单。1.在实体类上加上[JsonObject(MemberSerialization.OptOut)] 2.在不需要返回的属性上加上 [JsonIgnore]说明。
[DefaultValue(10)] public int Age { get; set; } Person p = new Person { Age = 10,Name = "张三丰",Sex = "男",IsMarry = false,Birthday = new DateTime(1991,1,2) }; JsonSerializerSettings jsetting=new JsonSerializerSettings(); jsetting.DefaultValueHandling=DefaultValueHandling.Ignore; Console.WriteLine(JsonConvert.SerializeObject(p,Formatting.Indented,jsetting)); 三.空值的处理
Person p = new Person { room=null,Age = 10,2) }; JsonSerializerSettings jsetting=new JsonSerializerSettings(); jsetting.NullValueHandling = NullValueHandling.Ignore; Console.WriteLine(JsonConvert.SerializeObject(p,jsetting)); 2.JsonProperty [JsonProperty(NullValueHandling=NullValueHandling.Ignore)] public Room room { get; set; } 四.支持非公共成员
[JsonProperty] private int Height { get; set; } 五.日期处理
[JsonConverter(typeof(IsoDateTimeConverter))] public DateTime Birthday { get; set; } 但是IsoDateTimeConverter日期格式不是我们想要的,我们可以继承该类实现自己的日期
//自己实现了一个yyyy-MM-dd格式化转换类,可以看到只是初始化IsoDateTimeConverter时给的日期格式为yyyy-MM-dd即可 public class ChinaDateTimeConverter : 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); } } [JsonConverter(typeof(ChinaDateTimeConverter))] public DateTime Birthday { get; set; } 八.枚举值的自定义格式化问题 public enum NotifyType { /// <summary> /// Emil发送 /// </summary> Mail=0,/// <summary> /// 短信发送 /// </summary> SMS=1 } public class TestEnmu { /// <summary> /// 消息发送类型 /// </summary> public NotifyType Type { get; set; } } JsonConvert.SerializeObject(new TestEnmu()); 输出结果:"Type":0 现在改造一下,输出"Type":"Mail"
public class TestEnmu { /// <summary> /// 消息发送类型 /// </summary> [JsonConverter(typeof(StringEnumConverter))] public NotifyType Type { get; set; } } 其它的都不变,在Type属性上加上了JsonConverter(typeof(StringEnumConverter))表示将枚举值转换成对应的字符串,而StringEnumConverter是Newtonsoft.Json内置的转换类型,最终输出结果 public class BoolConvert : JsonConverter { private string[] arrBString { get; set; } public BoolConvert() { arrBString = "是,否".Split(','); } /// <summary> /// 构造函数 /// </summary> /// <param name="BooleanString">将bool值转换成的字符串值</param> public BoolConvert(string BooleanString) { if (string.IsNullOrEmpty(BooleanString)) { throw new ArgumentNullException(); } arrBString = BooleanString.Split(','); if (arrBString.Length != 2) { throw new ArgumentException("BooleanString格式不符合规定"); } } public override object ReadJson(JsonReader reader,JsonSerializer serializer) { bool isNullable = IsNullableType(objectType); Type t = isNullable ? Nullable.GetUnderlyingType(objectType) : objectType; if (reader.TokenType == JsonToken.Null) { if (!IsNullableType(objectType)) { throw new Exception(string.Format("不能转换null value to {0}.",objectType)); } return null; } try { if (reader.TokenType == JsonToken.String) { string boolText = reader.Value.ToString(); if (boolText.Equals(arrBString[0],StringComparison.OrdinalIgnoreCase)) { return true; } else if (boolText.Equals(arrBString[1],StringComparison.OrdinalIgnoreCase)) { return false; } } if (reader.TokenType == JsonToken.Integer) { //数值 return Convert.ToInt32(reader.Value) == 1; } } catch (Exception ex) { throw new Exception(string.Format("Error converting value {0} to type '{1}'",reader.Value,objectType)); } throw new Exception(string.Format("Unexpected token {0} when parsing enum",reader.TokenType)); } /// <summary> /// 判断是否为Bool类型 /// </summary> /// <param name="objectType">类型</param> /// <returns>为bool类型则可以进行转换</returns> public override bool CanConvert(Type objectType) { return true; } public bool IsNullableType(Type t) { if (t == null) { throw new ArgumentNullException("t"); } return (t.BaseType.FullName=="System.ValueType" && t.GetGenericTypeDefinition() == typeof(Nullable<>)); } public override void WriteJson(JsonWriter writer,JsonSerializer serializer) { if (value == null) { writer.WriteNull(); return; } bool bValue = (bool)value; if (bValue) { writer.WriteValue(arrBString[0]); } else { writer.WriteValue(arrBString[1]); } } } 自定义了BoolConvert类型,继承自JsonConverter。构造函数参数BooleanString可以让我们自定义将true false转换成相应字符串。下面看实体里面怎么使用这个自定义转换类型
public class Person { [JsonConverter(typeof(BoolConvert))] public bool IsMarry { get; set; } } 相应的有什么个性化的转换需求,都可以使用自定义转换类型的方式实现。
Newtonsoft.Json.JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings(); JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() => { //日期类型默认格式化处理 setting.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat; setting.DateFormatString = "yyyy-MM-dd HH:mm:ss"; //空值处理 setting.NullValueHandling = NullValueHandling.Ignore; //高级用法九中的Bool类型转换 设置 setting.Converters.Add(new BoolConvert("是,否")); return setting; });这样设置以后,以后使用序列化的地方就不需要单独设置了,个人最喜欢设置的是空值处理这一块。 总结 Newtonsoft.Json序列化库替我们想了很多特性,也实现了很多特性,除了上面介绍的几种高级用法外,还有其它的特殊用法,可以去官网进行学习。当然这里我目前最喜欢的特性就是那个忽略部分属性序列化的功能,很小的代码改动实现了接口的优化,提升了用户体验。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |