使用Serialization序列化
IContractResolver接口提供了一种自定义方式,自定义JsonSerializer如何把.NET对象序列化为JSON,以及如何把JSON反序列化为.NET对象,而不需要在你的类上放置任何特性。
任何可以在对象、集合、属性等元素上设置的、使用特性或方法来控制序列化的功能,使用一个IContractResolver来设置。
- DefaultContractResolver
- CamelCasePropertyNamesContractResolver
- Custom IContractResolver Examples
Note |
---|
为了提高性能,你应该创建一次契约解析器,并尽可能重用实例。解析契约很慢,而且IContractResolver的实现通常会缓存契约。 |
DefaultContractResolver
DefaultContractResolver是Json.NET序列化器所使用的默认解析器。它以可重写的虚拟方法的形式提供了很多扩展扩展途径。
CamelCasePropertyNamesContractResolver
CamelCasePropertyNamesContractResolver继承自DefaultContractResolver,简单重写了JSON的属性名称,改成驼峰大小写的形式。
ContractResolver
Product product = new Product
{
ExpiryDate = new DateTime(2010, 12, 20, 18, 1, 0, DateTimeKind.Utc),
Name = "Widget",
Price = 9.99m,
Sizes = new[] { "Small", "Medium", "Large" }
};
string json =
JsonConvert.SerializeObject(
product,
Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);
//{
// "name": "Widget",
// "expiryDate": "2010-12-20T18:01:00Z",
// "price": 9.99,
// "sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
自定义IContractResolver的示例
使用JsonConverter配合IContractResolver
public class ConverterContractResolver : DefaultContractResolver
{
public new static readonly ConverterContractResolver Instance = new ConverterContractResolver();
protected override JsonContract CreateContract(Type objectType)
{
JsonContract contract = base.CreateContract(objectType);
// this will only be called once and then cached
if (objectType == typeof(DateTime) || objectType == typeof(DateTimeOffset))
{
contract.Converter = new JavaScriptDateTimeConverter();
}
return contract;
}
}
此示例使用一个IContract解析器为一个对象设置了JsonConverter。此处使用一个契约解析器是很有用的,因为DateTime不是你自己的类型,不可能在它上面放一个JsonConvertAttribute。
带有IContractResolver的条件属性
public class ShouldSerializeContractResolver : DefaultContractResolver
{
public new static readonly ShouldSerializeContractResolver Instance = new ShouldSerializeContractResolver();
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty property = base.CreateProperty(member, memberSerialization);
if (property.DeclaringType == typeof(Employee) && property.PropertyName == "Manager")
{
property.ShouldSerialize =
instance =>
{
Employee e = (Employee)instance;
return e.Manager != e;
};
}
return property;
}
}
此示例利用IContractResolver设置了针对属性的有条件序列化。如果你想要有条件地序列化一个属性,但是不想对你的类型添加额外的方法,IContractResolver就很有用。