Json.NET不会序列化事件,因此存储库基本类型中的
public event PropertyChangedEventHandlerPropertyChangedin
(序列化)期间不应引起问题。
PropertyChangedbase
HousePlan
但是,该存储库中的至少一种类型具有一个
System.Action委托而不是一个值更改时要处理的事件,尤其是
BindablePoint:
public class BindablePoint: PropertyChangedbase{ public double X { get { return Value.X; } set { Value = new Point(value, Value.Y); } } public double Y { get { return Value.Y; } set { Value = new Point( Value.X, value); } } private Point _value; public Point Value { get { return _value; } set { _value = value; onPropertyChanged("Value"); onPropertyChanged("X"); onPropertyChanged("Y"); if (ValueChanged != null) ValueChanged(); } } // This property is causing problems for Json.NET public Action ValueChanged;}目前尚不清楚为什么为此目的使用委托而不是事件,但是
System.ActionJson.NET不能反序列化。实际上,序列化和反序列化这些委托没有任何意义,因为它们在构造函数中分配给
Node:
public class Node: DiagramObject{ public Node() { Size.ValueChanged = RecalculateSnaps; Location.ValueChanged = RecalculateSnaps; }一种简单的解决方案是用
[JsonIgnore]
[JsonIgnore] public Action ValueChanged;
第二种简单的解决方案是用适当的事件替换委托,Json.NET现在将忽略该事件:
public event EventHandler ValueChanged;
如果出于某种原因无法更改这些类型,则可以创建一个自定义
ContractResolver,该自定义自动忽略所有委托类型属性:
public class IgnorePropertiesOfTypeContractResolver<T> : IgnorePropertiesOfTypeContractResolver{ // As of 7.0.1, Json.NET suggests using a static instance for "stateless" contract resolvers, for performance reasons. // http://www.newtonsoft.com/json/help/html/ContractResolver.htm // http://www.newtonsoft.com/json/help/html/M_Newtonsoft_Json_Serialization_DefaultContractResolver__ctor_1.htm // "Use the parameterless constructor and cache instances of the contract resolver within your application for optimal performance." static IgnorePropertiesOfTypeContractResolver<T> instance; static IgnorePropertiesOfTypeContractResolver() { instance = new IgnorePropertiesOfTypeContractResolver<T>(); } public static IgnorePropertiesOfTypeContractResolver<T> Instance { get { return instance; } } public IgnorePropertiesOfTypeContractResolver() : base(new[] { typeof(T) }) { }}/// <summary>/// Contract resolver to ignore properties of any number of given types./// </summary>public class IgnorePropertiesOfTypeContractResolver : DefaultContractResolver{ readonly HashSet<Type> toIgnore; public IgnorePropertiesOfTypeContractResolver(IEnumerable<Type> toIgnore) { if (toIgnore == null) throw new ArgumentNullException(); this.toIgnore = new HashSet<Type>(toIgnore); } protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); if (property.PropertyType.baseTypesAndSelf().Any(t => toIgnore.Contains(t))) { property.Ignored = true; } return property; }}public static class TypeExtensions{ public static IEnumerable<Type> baseTypesAndSelf(this Type type) { while (type != null) { yield return type; type = type.baseType; } }}现在使用以下设置进行序列化:
var settings = new JsonSerializerSettings{ PreserveReferencesHandling = PreserveReferencesHandling.Objects, ContractResolver = IgnorePropertiesOfTypeContractResolver<System.Delegate>.Instance,};该
ValueChanged属性将不再被序列化或反序列化。



