Search code examples
c#.netwindows-phone-7windows-8.net-4.5

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.


Solution

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