Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Client how can I deserialize an incompatible date format from the JSON response?

I have scoured the Net for info on this, but most of the results are about creating WCF services or situations where the service is under your control.

I am building a WCF client proxy for a RESTful JSON service which is out of my control. I am using the basic ServiceContract/DataContract pattern, and trying to let the framework do as much of the work as possible.

Mostly this is working fine, but all the datetime fields coming from this external service are in a particular format, e.g.

{"SomeObject": 
    {"details":"blue and round", "lastmodified":"2013/01/02 23:14:55 +0000"}
}

So I get an error:

There was an error deserializing the object of type MyNamespace.SomeObject. DateTime content '2013/01/02 23:14:55 +0000' does not start with '/Date(' and end with ')/' as required for JSON.'.

My datacontract is:

namespace Marshmallow.WebServices.ServiceModels
{
    [DataContract]
    public class SomeObject
    {
        [DataMember(Name = "details")]
        public string Details { get; set; }

        [DataMember(Name = "lastmodified")]
        public DateTime LastModified { get; set; }
    }
}

My servicecontract is:

[ServiceContract]
public interface ICoolExternalApi
{
    [OperationContract]
    [WebGet(UriTemplate = "/something.json",
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.Wrapped)]
    [return: MessageParameter(Name = "SomeObject")]
    SomeObject GetAccount();
}

What I want to know is, where can I stick some code to define how WCF should deserialize the lastmodified field (make a DateTime object out of the string)?

Or better yet, define how to deserialize all DateTime DataMembers for all my DataContracts. I do not want a lot of repeated code.

I also do not want to resort to some third-party deserializer nor do I want to start putting everything else through a custom deserialization method, if it is avoidable.

like image 899
Jordan Morris Avatar asked Jan 04 '13 14:01

Jordan Morris


1 Answers

Two things I can think of:

  1. Change LastModified to be a string and then convert it to a Datetime object yourself. It would mean exposing two properties for the same data on your object though.
  2. Write a IDispatchMessageInspector to intercept the message before the deserialization occurs and massage the raw message using regex. It would allow a one stop solution for all dates in your service.
like image 110
Mike Parkhill Avatar answered Sep 25 '22 12:09

Mike Parkhill