Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DataContractJsonSerializer parsing iso 8601 date

I have a json which has date as 2012-06-07T00:29:47.000 and has to be deserialized. But on

 DataContractJsonSerializer serializer = new DataContractJsonSerializer(type);
 return (object)serializer.ReadObject(Util.GetMemoryStreamFromString(json));

I get below exception

There was an error deserializing the object of type System.Collections.Generic.List`1
[[MyNameSpace.MyClass, MyNameSpace, Version=1.0.4541.23433, Culture=neutral, PublicKeyToken=null]].
 DateTime content '2012-06-07T00:29:47.000' does not start with '\/Date(' and end with ')\/' as required for JSON

It is working in windows mobile 7 but the same code is not working in windows 8.
It is expecting date format as \/Date(1337020200000+0530)\/ instead of 2012-06-07T00:29:47.000.

Does it require custom serialization if yes then how? And I can't use JSON.NET I'm bound to use DataContractJsonSerializer and I can't change the format of the JSON as the same JSON is used for android.
I'm new in .net. Thanks.

like image 490
Inder Kumar Rathore Avatar asked Jun 08 '12 08:06

Inder Kumar Rathore


2 Answers

Use one string property for serialisation/deserialisation, and a separate, non-serialised property that converts it to a DateTime. Easier to see some sample code:

[DataContract]
public class LibraryBook
{
    [DataMember(Name = "ReturnDate")]
    // This can be private because it's only ever accessed by the serialiser.
    private string FormattedReturnDate { get; set; }

    // This attribute prevents the ReturnDate property from being serialised.
    [IgnoreDataMember]
    // This property is used by your code.
    public DateTime ReturnDate
    {
        // Replace "o" with whichever DateTime format specifier you need.
        // "o" gives you a round-trippable format which is ISO-8601-compatible.
        get { return DateTime.ParseExact(FormattedReturnDate, "o", CultureInfo.InvariantCulture); }
        set { FormattedReturnDate = value.ToString("o"); }
    }
}

You could do the parsing in the setter of FormattedReturnDate instead, to allow it to fail earlier if a bad date is received.


Edited to include GôTô's suggestion to give the serialised DataMember the right name.

like image 122
anton.burger Avatar answered Nov 05 '22 02:11

anton.burger


Pass the format in DataContractJsonSerializer constructor

var serializer = new DataContractJsonSerializer(
   typeof(Client),
   new DataContractJsonSerializerSettings {
       DateTimeFormat = new DateTimeFormat("yyyy-MM-dd hh:mm:ss"),
    });
like image 22
techExplorer Avatar answered Nov 05 '22 01:11

techExplorer