在反序列化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;
}
}
添加回调但从未调用。
答案 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。