まずはシリアライズとJavascriptの側でいくつかの問題を抱えていました。 DateTimeの値は、最初にマシンのローカルタイムゾーンと一致するように2回シフトされ、ブラウザのタイムゾーンと一致します。カスタムコンバーターをJavaScriptSerializerに追加することで修正しました。 DateTimeは、SerializeオーバーライドでDateTimeKind.Utcに設定されています。バックのSerializeからデータを供給するために少し大変だったが、我々はいくつかのウリは、同じJavaScriptSerializer /日(286769410010)/フォーマットではなく現地時間に移行することなく、DateTimeの値を返すために役立っているハックました。 Javascript側では、構築されたDate()オブジェクトをオフセットするためにKendoUI JSライブラリにパッチを適用し、UTCであるかのように表示しました。
はその後、我々は、他の側に、デシリアライゼーションを動作するように始めました。ここでも、JSON.stringifyの代わりにカスタムのstringifyを使用するようにコードを調整しなければなりませんでした。これは、現地時間からUTCに変換するときにデータを再度オフセットします。これまでのところすべてが良いようだった。
しかし、このテストを見て:
public void DeserialiseDatesTest()
{
var dateExpected = new DateTime(1979, 2, 2,
2, 10, 10, 10, DateTimeKind.Utc);
// this how the Dates look like after serializing
// anothe issue, unrelated to the core problem, is that the "\" might get stripped out when dates come back from the browser
// so I have to add missing "\" or else Deserialize will break
string s = "\"\\/Date(286769410010)\\/\"";
// this get deserialized to UTC date by default
JavaScriptSerializer js = new JavaScriptSerializer();
var dateActual = js.Deserialize<DateTime>(s);
Assert.AreEqual(dateExpected, dateActual);
Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind);
// but some Javascript components (like KendoUI) sometimes use JSON.stringify
// for Javascript Date() object, thus producing the following:
s = "\"1979-02-02T02:10:10Z\"";
dateActual = js.Deserialize<DateTime>(s);
// If your local computer time is not UTC, this will FAIL!
Assert.AreEqual(dateExpected, dateActual);
// and the following fails always
Assert.AreEqual(DateTimeKind.Utc, dateActual.Kind);
}
なぜJavaScriptSerializerは現地時間に\/Date(286769410010)\/
UTC時刻に文字列が、1979-02-02T02:10:10Z
をデシリアライズしますか?
私たちは、カスタムJavascriptConverter
に逆シリアル化メソッドを追加しようとしましたが、問題は、私たちのJavascriptConverterには次の種類がある場合はデシリアライズが呼び出されないということです。
public override IEnumerable<Type> SupportedTypes
{
get { return new List<Type>() { typeof(DateTime), typeof(DateTime?) }; }
}
私は推測する、デシリアライズのみSupportedTypes
場合に呼び出されますDateTimeフィールドを持つ複雑なエンティティのいくつかの種類が含まれています。
- デシリアライズはUTCといくつかのように、いくつかの日付をデシリアライズ
- Serializeをアカウントにすべてのデータ項目のSupportedTypesでシンプルなタイプがかかりますが、逆シリアル化は、単純型のためにそれを無視します:
ので、
JavaScriptSerializer
とJavascriptConverter
は2つの矛盾を持っています - 現地時間として。
これらの問題を解決するための任意の簡単な方法はありますか? JavaScriptSerializer
をいくつかの他のシリアライザと置き換えるのは少し怖いです。私たちが使っているサードパーティのライブラリのいくつかは、ある種の "機能/バグ"であるJavaScriptSerializer
に依存しているかもしれないからです。
Ok - これはすべてうまくいいものですが、より良いjsonライブラリを出荷してバグのJavaScriptSerializerだけを残すのではなく、Msftの言い訳は何ですか? – nothingisnecessary