在反序列化期间,DataContractJsonSerializer将字典中的DateTime值字符串化

时间:2019-01-07 23:42:32

标签: c# json serialization json-deserialization datacontractjsonserializer

我需要.NET随附的JSON序列化器/反序列化器。我不能使用Newtonsoft Json.NET。

据我所知,剩下的是 JavaScriptSerializer DataContractJsonSerializer 。 JavaScriptSerializer不能正常工作,因为它坚持日期时间的某种愚蠢格式,该格式在反序列化后会丢失UTC偏移量,请不要担心。

我正在使用 DataContractJsonSerializer ,下面的测试方法显示了错误。 我正在为序列化和反序列化指定自定义日期格式(ISO),并且字符串看起来不错。此外,Json.NET可以正确读取它。

如何在不进行任何正则表达式和手动转换的情况下有效而通用地解决此问题?

[Test]
    public void SerializerFailure()
    {
       TestObject testObject = new TestObject() {Dict = new Dictionary<string, object>() {{"DateTest", DateTime.UtcNow}, {"DecimalTest", 66.6M}}};
        Assert.IsInstanceOf<DateTime>(testObject.Dict["DateTest"]);

        string serialized = this.Serialize(testObject);
        //output is OK...

        //{"Dict":{"DateTest":"2019-01-07T23:16:59.5142225Z","DecimalTest":66.6}}
        TestObject deserialized = this.Deserialize<TestObject>(serialized);
        Assert.IsInstanceOf<string>(deserialized.Dict["DateTest"]);

        TestObject newtonDeserialized = JsonConvert.DeserializeObject<TestObject>(serialized);
        testObject.ShouldBeEquivalentTo(newtonDeserialized); //passes OK


        testObject.ShouldBeEquivalentTo(deserialized); //Fails

        //ERROR: Expected member Dict[DateTest] to be 
        //      "2019-01-07T23:27:23.0758967Z" with a length of 28, but
        //      "07.01.2019 23:27:23" has a length of 19.
        //          Expected member Dict[DateTest] to be
        //      "2019-01-07T23:27:23.0758967Z", but
        //      "07.01.2019 23:27:23" differs near "07."(index 0).

    }

序列化:

    public string Serialize(object objectToPost)
    {
        using (MemoryStream stream = new System.IO.MemoryStream())
        {
            var settings = new DataContractJsonSerializerSettings() { DateTimeFormat = new DateTimeFormat("O"), UseSimpleDictionaryFormat = true };

            DataContractJsonSerializer serializer
                = new DataContractJsonSerializer(objectToPost.GetType(), settings);
            serializer.WriteObject(stream, objectToPost);
            stream.Flush();
            stream.Seek(0, SeekOrigin.Begin);
            using (StreamReader reader = new StreamReader(stream))
            {
                return reader.ReadToEnd();
            }
        }
    }

反序列化

    public T Deserialize<T>(string stringContent)
    {
        try
        {
            using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(stringContent)))
            {
                var settings = new DataContractJsonSerializerSettings() { DateTimeFormat = new DateTimeFormat("O"), UseSimpleDictionaryFormat = true };
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), settings);
                return (T)serializer.ReadObject(ms);
            }
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"Error while deserializing string as {typeof(T).Name}", ex);
        }

    }

0 个答案:

没有答案