C# 反序列化 Json 对象 - DateTime

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14043412/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 10:30:36  来源:igfitidea点击:

Deserialize Json Object - DateTime

c#wpfweb-servicesmicrosoft-metro

提问by Sam_vdd

My web-apireturns an User Object. In that object there is a DateTimeproperty. When i'am reading it in my Application i get an error because the string that would represent the DateTime isn't valid it's missing \Date ...

web-api返回一个用户对象。在那个对象中有一个DateTime属性。当我在我的应用程序中阅读它时,我收到一个错误,因为代表 DateTime 的字符串无效它丢失了\Date ...

{System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type User. DateTime content '1984-10-02T01:00:00' does not start with '/Date(' and end with ')/' as required for JSON. --->

{System.Runtime.Serialization.SerializationException:反序列化用户类型的对象时出错。DateTime 内容 '1984-10-02T01:00:00' 不以 '/Date(' 开头并以 ')/' 结尾,这不是 JSON 所要求的。--->

public static async Task<User> GetUser(string email)
    {
        try
        {
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(url + "?email="+email);
                if (response.IsSuccessStatusCode)
                {
                    string content = await response.Content.ReadAsStringAsync();
                    User user = DataService.Deserialize<User>(content);
                    return user;
                }
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }

This is the method i use to deserialize.

这是我用来反序列化的方法。

public static T Deserialize<T>(string json) {
        try
        {
            var _Bytes = Encoding.Unicode.GetBytes(json);
            using (MemoryStream _Stream = new MemoryStream(_Bytes))
            {

                var _Serializer = new DataContractJsonSerializer(typeof(T));

                return (T)_Serializer.ReadObject(_Stream);
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

采纳答案by Sam_vdd

I found how to fix it when adding the package Json.net (Newtonsoft.Json).

我在添加包 Json.net (Newtonsoft.Json) 时发现了如何修复它。

public async static Task<T> Deserialize<T>(string json)
    {
        var value = await Newtonsoft.Json.JsonConvert.DeserializeObjectAsync<T>(json);
        return value;
    }

回答by theMayer

To get around this, probably the easiest way is to set the value type on your DataContract type to 'string'. Then, if you need to work with .NET datetimes, you will need to do a DateTime.Parse on your string value. This will eliminate your deserialization problem. It's likely that the original class that was serialized used a string value to begin with, since it is missing the required formatting for dates.

要解决这个问题,可能最简单的方法是将 DataContract 类型的值类型设置为“字符串”。然后,如果您需要使用 .NET 日期时间,则需要对字符串值执行 DateTime.Parse。这将消除您的反序列化问题。序列化的原始类很可能使用字符串值开始,因为它缺少日期所需的格式。

Note that when you do a DateTime.Parse, if the time zone information is present, it will convert it to the local time of your computer (this is stupid, I know). Just FYI.

请注意,当您执行 DateTime.Parse 时,如果存在时区信息,它会将其转换为您计算机的本地时间(这很愚蠢,我知道)。仅供参考。

回答by Kamyar Nazeri

There's no standard format for exchanging dates in the JSON specification, which is why there are so many different heterogeneous formats of dates in JSON!

JSON 规范中没有用于交换日期的标准格式,这就是为什么JSON 中有这么多不同的异构日期格式!

DataContractJsonSerializerserializes date in the format counting msecs since 1970 surrounded by Date()something like this: Date(1335205592410)and expects the same format to deserialize back to DateTime. However what you are getting as a JSON date string is a ISO8601 format which is the format most browsers/softwares today use to serialize dates!

DataContractJsonSerializer以自 1970 年以来计数毫秒的格式序列化日期,周围Date()是这样的:Date(1335205592410)并期望相同的格式反序列化回DateTime. 但是,您作为 JSON 日期字符串获得的是 ISO8601 格式,这是当今大多数浏览器/软件用于序列化日期的格式!

JavaScriptSerializeris an alternative JSON serializer in .Net which can pretty much serialize any type, including anonymous types to or from JSON string, and it is capable of deserializing JSON dates either in ISO8601 format or the format DataContractJsonSerializerprovides.

JavaScriptSerializer是 .Net 中的替代 JSON 序列化程序,它几乎可以将任何类型序列化,包括与 JSON 字符串之间的匿名类型,并且它能够以 ISO8601 格式或DataContractJsonSerializer提供的格式反序列化 JSON 日期。

Using JavaScriptSerializer, your Deserialize method would look like this:

使用JavaScriptSerializer,您的反序列化方法将如下所示:

public static T Deserialize<T>(string json)
{
    return new JavaScriptSerializer().Deserialize<T>(json);
}

回答by Mats Magnem

Could it be that the DateTime is actually coming back as a "nullable", like "DateTime?" (with the question mark)?

难道 DateTime 实际上是作为“可空”返回的,比如“DateTime”?(带问号)?

Because then, it could be NULL, as and ".HasValue == false".

因为那样,它可能是 NULL,因为和“.HasValue == false”。

Only guessing here... :-)

只是在这里猜测... :-)

回答by Charles

Just change the DateTimeFormat on your DataContractJsonSerializer like so:

只需像这样更改 DataContractJsonSerializer 上的 DateTimeFormat :

    public static T Deserialize<T>(string json) {
    try
    {
        var settings = new DataContractJsonSerializerSettings 
        {
            DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("o")
        };
        var _Bytes = Encoding.Unicode.GetBytes(json);
        using (MemoryStream _Stream = new MemoryStream(_Bytes))
        {

            var _Serializer = new DataContractJsonSerializer(typeof(T), settings);

            return (T)_Serializer.ReadObject(_Stream);
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}