Probleme mit JavaScriptSerializer UTC DateTime

Unser Kunde wollte die Datums- und Zeitwerte im Browser genauso anzeigen, wie sie in der Datenbank sind, und wir speichern sie als UTC in der Datenbank.

Anfangs hatten wir einige Probleme mit der Serialisierung und der Javascript-Seite. Die DateTime-Werte wurden zweimal verschoben - zunächst um die lokale Zeitzone des Computers und dann um die Zeitzone im Browser abzugleichen. Wir haben dies behoben, indem wir dem JavaScriptSerializer einen benutzerdefinierten Konverter hinzugefügt haben. Wir haben DateTime als DateTimeKind.Utc in der Serialize-Überschreibung markiert. Es war etwas schwierig, die Daten von Serialize zurückzuspeisen, aber wir fanden einen Uri-Hack, der dazu beitrug, DateTime-Werte im gleichen JavaScriptSerializer / Date (286769410010) / -Format zurückzugeben, ohne jedoch auf die lokale Zeit zu verschieben. Auf der Javascript-Seite haben wir die KendoUI JS-Bibliothek gepatcht, um die konstruierten Date () -Objekte so zu versetzen, dass sie als UTC-Objekte erscheinen.

Dann begannen wir auf der anderen Seite mit der Deserialisierung. Auch hier mussten wir unseren Code anpassen, um anstelle von JSON.stringify einen benutzerdefinierten Stringify zu verwenden, der die Daten beim Konvertieren von der lokalen Zeit in UTC wieder versetzt. Bisher schien alles gut zu sein.

Aber sieh dir diesen Test an:

    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); 
    }

Warum deserialisiert JavaScriptSerializer?\/Date(286769410010)\/ Zeichenketten zu UTC-Zeit aber1979-02-02T02:10:10Zzur Ortszeit?

Wir haben versucht, unserer benutzerdefinierten Methode eine Deserialize-Methode hinzuzufügenJavascriptConverter Das Problem ist jedoch, dass Deserialize niemals aufgerufen wird, wenn unser JavascriptConverter die folgenden Typen hat:

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new List<Type>() { typeof(DateTime), typeof(DateTime?) }; }
    }

Ich denke, Deserialize würde nur dann aufgerufen, wennSupportedTypes enthielt Typen einiger komplexer Entitäten mit DateTime-Feldern.

So,JavaScriptSerializer undJavascriptConverter haben zwei Inkonsistenzen:

Serialize berücksichtigt einfache Typen in SupportedTypes für jedes Datenelement, Deserialize ignoriert sie jedoch für einfache TypenDeserialize deserialisiert einige Datumsangaben als UTC und einige als Ortszeit.

Gibt es eine einfache Möglichkeit, diese Probleme zu beheben? Wir haben ein bisschen Angst zu ersetzenJavaScriptSerializer mit einem anderen Serializer, da möglicherweise einige der Bibliotheken von Drittanbietern, die wir verwenden, sich auf bestimmte "Funktionen / Fehler" von verlassenJavaScriptSerializer.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage