NewtonSoft JsonContract OnDeserializedCallbacks没有调用原始类型?

时间:2016-10-20 14:43:56

标签: c# json.net

在反序列化DateTime之后,我想在中心位置做一些事情。所以我想把一个回调挂钩到合约,但它们永远不会被调用。 有什么想法吗?

    public class MyContractResolver : DefaultContractResolver
    {
        protected override JsonContract CreateContract(Type objectType)
        {
            var result = base.CreateContract(objectType);
            var primContract = result as JsonPrimitiveContract;
            if (primContract != null && primContract.CreatedType == typeof(DateTime))
            {
                primContract.OnDeserializingCallbacks.Add((o, context) =>
                {
                    var test = o;
                });
                primContract.OnDeserializedCallbacks.Add((o, context) =>
                {
                    var test = o;
                });
            }
            return result;
        }
    }

添加回调但从未调用。

1 个答案:

答案 0 :(得分:0)

你是对的 - 我能够重现这个(演示fiddle)。

更奇怪的是,对于安装了TypeConverter的非原始类型(例如System.Drawing.Color),由JsonStringContract处理,OnSerializing和{{1调用回调函数,但不调用相应的反序列化回调函数。

您可能想要report an issue

与此同时,你可以继承IsoDateTimeConverter或继承自DateTimeConverterBase的其他转换器,并在那里添加回调:

OnSerialized

请注意,对于具有值语义的public class MyContractResolver : DefaultContractResolver { protected override JsonContract CreateContract(Type objectType) { var result = base.CreateContract(objectType); var primContract = result as JsonPrimitiveContract; if (primContract != null && (primContract.CreatedType == typeof(DateTime) || primContract.CreatedType == typeof(DateTime?)) && primContract.Converter == null ) { //Console.WriteLine("Adding {0} callbacks for {1}", primContract.ToString(), objectType.ToString()); var converter = new MyIsoDateTimeConverter(); converter.OnDeserializingCallbacks.Add((o, context) => { Console.WriteLine("Deserializing " + o); }); converter.OnDeserializedCallbacks.Add((o, context) => { Console.WriteLine("Deserialized " + o); }); primContract.Converter = converter; } return result; } } class MyIsoDateTimeConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter { private List<SerializationCallback> _onDeserializingCallbacks; private List<SerializationCallback> _onDeserializedCallbacks; public IList<SerializationCallback> OnDeserializingCallbacks { get { if (_onDeserializingCallbacks == null) { Interlocked.CompareExchange(ref _onDeserializingCallbacks, new List<SerializationCallback>(), null); } return _onDeserializingCallbacks; } } public IList<SerializationCallback> OnDeserializedCallbacks { get { if (_onDeserializedCallbacks == null) { Interlocked.CompareExchange(ref _onDeserializedCallbacks, new List<SerializationCallback>(), null); } return _onDeserializedCallbacks; } } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var value = base.ReadJson(reader, objectType, existingValue, serializer); if (value != null && value is DateTime) { if (_onDeserializingCallbacks != null) { foreach (var callback in _onDeserializingCallbacks) callback(value, serializer.Context); } if (_onDeserializedCallbacks != null) { foreach (var callback in _onDeserializedCallbacks) callback(value, serializer.Context); } } return value; } } 类型,在构造对象之后但在填充之前调用DateTime事件没有意义,因为对象在施工时完全填满。因此,我在反序列化后调用了两个事件。

另外,请仔细阅读Serializing Dates in JSON以确保OnDeserializing符合您的需求。

示例fiddle