NewtonSoft JsonContract ondeserializedcallback未被基本类型调用
本文关键字:类型 调用 JsonContract ondeserializedcallback NewtonSoft | 更新日期: 2023-09-27 18:14:13
在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;
}
}
回调函数被添加但从未被调用。
你是对的-我能够复制这个(演示小提琴)。
更奇怪的是,对于安装了TypeConverter
的非基本类型(例如System.Drawing.Color
),因此由JsonStringContract
处理,调用OnSerializing
和OnSerialized
回调,但不调用相应的反序列化回调。
您可能想要报告一个问题。
同时,你可以子类化IsoDateTimeConverter
或其他继承DateTimeConverterBase
的转换器,并在那里添加回调:
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
这样具有值语义的类型,在对象构造完成之后但在填充之前调用OnDeserializing
事件是没有意义的,因为对象在构造完成时已经完全填充了。因此,我在反序列化之后调用了这两个事件。
另外,阅读JSON中的序列化日期以确保IsoDateTimeConverter
将满足您的需求。
小提琴例子。