JavaScriptSerializer UTC Problemy z DateTime

Nasz klient chciał pokazać wartości daty i godziny w przeglądarce dokładnie tak, jak w bazie danych, a my przechowujemy je jako UTC w bazie danych.

Na początku mieliśmy pewne problemy z serializacją i stroną JavaScript. Wartości DateTime zostały przesunięte dwukrotnie - najpierw, aby dopasować lokalną strefę czasową komputera, a następnie dopasować strefę czasową w przeglądarce. Naprawiliśmy to, dodając niestandardowy konwerter do JavaScriptSerializer. Oznaczono DateTime jako DateTimeKind.Utc w zastępowaniu Serialize. Dostarczenie danych z Serialize było trochę trudne, ale znaleźliśmy kilka hacków Uri, które pomogły zwrócić wartości DateTime w tym samym JavaScriptSerializer / Date (286769410010) / formacie, ale bez przesunięcia na czas lokalny. Po stronie Javascript załataliśmy bibliotekę KendoUI JS, aby skompensować skonstruowane obiekty Date (), tak aby wyglądały tak, jakby były UTC.

Potem zaczęliśmy pracować po drugiej stronie, deserializacja. Ponownie musieliśmy dostosować nasz kod, aby użyć niestandardowego stringify zamiast JSON.stringify, który ponownie przesuwa dane podczas konwersji z czasu lokalnego na UTC. Jak dotąd wszystko wydawało się dobre.

Ale spójrz na ten test:

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

Dlaczego JavaScriptSerializer jest deserializowany\/Date(286769410010)\/ ciągi do czasu UTC, ale1979-02-02T02:10:10Zdo czasu lokalnego?

Próbowaliśmy dodać metodę Deserialize do naszego zwyczajuJavascriptConverter ale problem polega na tym, że Deserialize nigdy nie jest wywoływane, jeśli nasz JavascriptConverter ma następujące typy:

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

Domyślam się, że Deserialize będzie nazywane tylko wtedy, gdySupportedTypes zawierały typy niektórych złożonych elementów, które mają pola DateTime.

Więc,JavaScriptSerializer iJavascriptConverter mają dwie niespójności:

Serialize uwzględnia proste typy w SupportedTypes dla każdego elementu danych, ale Deserialize ignoruje je dla prostych typówDeserialize deserializuje niektóre daty jako UTC, a niektóre - jako czas lokalny.

Czy jest jakiś prosty sposób na rozwiązanie tych problemów? Trochę się boimy zastąpićJavaScriptSerializer z jakimś innym serializatorem, ponieważ może niektóre z bibliotek innych firm, z których korzystamy, polegają na pewnych „funkcjach / błędach”JavaScriptSerializer.

questionAnswers(1)

yourAnswerToTheQuestion