Deserialize Json Object - DateTime

50,348

Solution 1

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

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

Solution 2

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.

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.

Solution 3

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!

DataContractJsonSerializer serializes 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!

JavaScriptSerializer is 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 DataContractJsonSerializer provides.

Using JavaScriptSerializer, your Deserialize method would look like this:

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

Solution 4

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

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

Only guessing here... :-)

Solution 5

Just change the DateTimeFormat on your DataContractJsonSerializer like so:

    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;
    }
}
Share:
50,348
Sam_vdd
Author by

Sam_vdd

Updated on December 06, 2020

Comments

  • Sam_vdd
    Sam_vdd over 3 years

    My web-api returns an User Object. In that object there is a DateTime property. 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 ...

    {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. --->

    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;
            }
        }
    
  • Sam_vdd
    Sam_vdd over 11 years
    No it get a correct value "1984-10-02T01:00:00" just in another format
  • Sam_vdd
    Sam_vdd over 11 years
    The JavaScriptSerializer doesn't excist in a w8-app so what now? Is there a Nuget package or something?
  • Kamyar Nazeri
    Kamyar Nazeri over 11 years
    If your application is a WPF/Winforms that uses .Net 4.5, just add a reference to System.Web.Extensions, however if you are developing a WinRT application then you can either use System.Web.Extensions.dll or a third party library like JSON.net found here : nuget.org/packages/Newtonsoft.Json
  • Mats Magnem
    Mats Magnem over 11 years
    It seems like a default serialized format for DateTime.So it's strange that you get an exception. Maybe try Utf8 instead of Unicode when serializing and deserializing? Never had this problem myself.
  • Joel Barsotti
    Joel Barsotti over 9 years
    I tried this code and it doesn't seem to work for me.
  • Jerther
    Jerther over 9 years
    This worked for me. For example: DateTime.Parse("2014-11-04T05:00:00.000Z");
  • Gabriel Luca
    Gabriel Luca over 4 years
    Could you explain more where should this be used?