【问题标题】:Deserialize Json Object - DateTime反序列化 Json 对象 - 日期时间
【发布时间】:2012-12-26 16:38:53
【问题描述】:

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

{System.Runtime.Serialization.SerializationException: 有一个 反序列化用户类型的对象时出错。日期时间内容 '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;
        }
    }

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

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

【问题讨论】:

    标签: c# wpf web-services microsoft-metro


    【解决方案1】:

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

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

    【讨论】:

    • 这对我有用。例如:DateTime.Parse("2014-11-04T05:00:00.000Z");
    【解决方案2】:

    There's no standard format for exchanging dates in the JSON specification,这就是为什么 JSON 中有这么多不同的异构日期格式!

    DataContractJsonSerializer 以自 1970 年以来以毫秒为单位的格式序列化日期,由 Date() 包围,如下所示:Date(1335205592410) 并期望相同的格式反序列化回 DateTime。但是,您得到的 JSON 日期字符串是 ISO8601 格式,这是当今大多数浏览器/软件用来序列化日期的格式!

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

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

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

    【讨论】:

    • JavaScriptSerializer 在 w8-app 中不存在,那现在怎么办?有 Nuget 包之类的吗?
    • 如果您的应用程序是使用 .Net 4.5 的 WPF/Winforms,只需添加对 System.Web.Extensions 的引用,但是如果您正在开发 WinRT 应用程序,则可以使用 System.Web.Extensions.dll 或第三个像 JSON.net 这样的派对库可以在这里找到:nuget.org/packages/Newtonsoft.Json
    【解决方案3】:

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

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

    【讨论】:

    • 你能解释一下这个应该在哪里使用吗?
    【解决方案4】:

    会不会是 DateTime 实际上以“可为空”的形式返回,例如“DateTime”? (带问号)?

    因为那时,它可能是 NULL,as 和 ".HasValue == false"。

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

    【讨论】:

    • 不,它以另一种格式获得正确的值“1984-10-02T01:00:00”
    • 这似乎是 DateTime 的默认序列化格式。所以你得到一个异常很奇怪。也许在序列化和反序列化时尝试 Utf8 而不是 Unicode?我自己从来没有遇到过这个问题。
    【解决方案5】:

    只需像这样更改 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;
        }
    }
    

    【讨论】:

    • 我试过这段代码,但它似乎对我不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    相关资源
    最近更新 更多