あなたはそうです - これを再現できました(デモfiddle)。
TypeConverter
がJsonStringContract
によって処理されるように(例えばSystem.Drawing.Color
として)がインストールされ、持って非プリミティブ型のため、あっても他人は、OnSerializing
とOnSerialized
コールバックが呼び出され、なく、対応するデシリアライゼーションコールバックされます。
report an issueです。値の意味を持っているなど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.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;
}
}
注:なお
、あなたはIsoDateTimeConverter
またはDateTimeConverterBase
から継承他のいくつかのコンバータをサブクラス化でき、そこにコールバックを追加しますオブジェクトが構築された後、オブジェクトが作成される前にOnDeserializing
イベントを呼び出すことは、オブジェクトが構築時に完全に埋め込まれているためです。したがって、デシリアライズ後に両方のイベントを呼び出しました。
また、IsoDateTimeConverter
があなたのニーズを満たしていることを確認するためにSerializing Dates in JSONを読んでください。
例fiddle。
出典
2016-10-20 22:43:01
dbc
私が達成したいのはこれです:残りのAPIからUTCのdatetimes(Kind = UTC)を受け取りました。私はこれらを私のWebアプリケーションのユーザごとに設定されたタイムゾーンを使って、ローカルのdatetimeに変換します。私は中央の場所でそれをしたい。しかし、あなたが指摘したように、デシリアライズ時にこれを行うことはできません。datetimeはすでに構築されており、新しいインスタンスを返すことができないからです。だから、私はデフォルトのdatetime文字列セマンティクスでうまくいますが、コンバータを作成する必要があると思います。 –
@JaapMosselman - 独自の 'DateTime'コンバーターを作成し、' ReadJson() 'の最後に変更を加えることは、その時に行く方法のようです。スタックオーバーフローに関する質問の推奨形式は、[投稿ごとに1つの質問](https://meta.stackexchange.com/questions/222735/can- 1件につき1つの質問のみ)。 – dbc