首先我们定义如下的类型,我们希望JSON.NET反序列化对象时使用第2个构造函数,我们将第一个默认构造函数屏蔽,标记为私有private修饰符。第2个构造函数需要指定一个website对象作为参数,如果提供的参数为null则抛出异常:
public class Website { ; } private Website() { } website) { ); Url = website.Url; } }现在使用一般的方式反序列化一个JSON字符串。
; try { >(json); } ex) { Console.WriteLine(ex); } Value cannot be null.Parameter name: website我们发现该序列化方法抛出了异常,并没有按照我们预想的方式进行反序列化,JSON.NET提供如下的方式指定公有构造函数。
JsonSerializerSettings { ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }); Console.WriteLine(website.Url);另外,JSON.NET提供了指定任何构造函数的JsonConstructorAttribute特性,只需要在构造函数上标记,即可指定构造函数。
public class User { ; } ; } public User() { } [JsonConstructor] enabled) { UserName = userName; Enabled = enabled; } } ; >(json); Console.WriteLine(user.UserName);13、当对象的属性为默认值(0或null)时不序列化该属性
public class Person { ; } ; } ; } ; } } (); .Indented); Console.WriteLine(jsonIncludeDefaultValues); { "Name": null, "Age": 0, "Partner": null, "Salary": null } JsonSerializerSettings { DefaultValueHandling = DefaultValueHandling.Ignore }); Console.WriteLine(json); {} 14、反序列化时JSON属性与对象属性的数量必须一致默认情况下,JSON.NET反序列化并不要求JSON属性的数量与对象属性的数量相等,也就是始终保持有则序列化,无则不序列化的原则,不会抛出异常。但是,我们的需求并非这样,我们希望属性数量不等或者未提供值时,抛出异常,而不是正常反序列化,可以这样。
public class Account { ; } ; } } string json = @"{ 'FullName': 'Dan Deleted', 'Deleted': true, 'DeletedDate': '2013-01-20T00:00:00' }"; try { JsonSerializerSettings { MissingMemberHandling = MissingMemberHandling.Error }); } ex) { Console.WriteLine(ex.Message); } Could not find member 'DeletedDate' on object of type 'Account'. Path 'DeletedDate', line 4, position 23.这样,当未全部指定对象的属性时,就会抛出异常,而不是部分属性序列化。
15、JSON.NET中忽略null值得处理器 public class Person { ; } ; } ; } ; } } , Age = 1 }; .Indented); Console.WriteLine(jsonIncludeNullValues); { "Name": "Nigal Newborn", "Age": 1, "Partner": null, "Salary": null } JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); Console.WriteLine(json); { "Name": "Nigal Newborn", "Age": 1 }在上面的示例中,默认情况下JSON.NET会将对象的null属性值序列化为JSON中null值。当对象属性值为null时,可忽略序列化,只需要指定NullValueHandling即可,另外有一种场景是,当对象属性值为null时,需要替换为空字符串双引号,如何替换,请点击这里参阅零度的文章。
16、JSON.NET中循环引用的处理方法有的对象具有循环引用,对象的属性是对象本身,这会导致JSON.NET进入无限死循环,我们需要指定ReferenceLoopHandling打破这种循环引用。
public class Employee { ; } ; } } }; }; joe.Manager = mike; mike.Manager = mike; JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore }); Console.WriteLine(json); { "Name": "Joe User", "Manager": { "Name": "Mike Manager" } } 17、通过ContractResolver指定属性名首字母小写通常,在.NET中属性采用PascalCase规则(首字母大写),在JavaScript中属性名使用CamelCase规则(首字母小写),我们希望序列化后的JSON字符串符合CamelCase规则,JSON.NET提供的ContractResolver可以设置属性名小写序列化,更灵活的设置请点击这里参阅零度的文章。
public class Person { ; } ; } public string FullName { + LastName; } } } }; JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }); Console.WriteLine(json); { "firstName": "Sarah", "lastName": "Security", "fullName": "Sarah Security" } 18、JSON.NET中通过特性序列化枚举类型 public enum UserStatus { NotConfirmed, Active, Deleted } public class User { ; } [))] ; } }