Nodoid
Nodoid

Reputation: 1561

Deserialize JSON string to a class

I have a very simple DataContract class that I need to deserialise into. I'm not using JSON.NET for a particular reason so use DataContractJsonSerializer.

My contract class looks like this

[DataContract(Name = "d")]
    public class ResponseClass
    {
        [DataMember]
        public int ResponseCode
        { get; set;}
        [DataMember]
        public string ResponseMessage
        { get; set;}
        [DataMember]
        public string Response
        { get; set;}
    }

The service call is coming back with a valid Json string, but in deserialising, the value at the end is always 0 or string.Empty despite the value being passed in being non-0 or non string.Empty.

My deserialise code looks like this

    private string deserializeJSON(string resp, bool code = false)
    {
        string value = string.Empty;
        ResponseClass deserialized = null;
        using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(resp)))
        {
            stream.Position = 0;
            var ser = new DataContractJsonSerializer(typeof(ResponseClass));
            deserialized = ser.ReadObject(stream) as ResponseClass;
        }
        value = code ? deserialized.Response : deserialized.ResponseCode.ToString();
        return value;
    }

I've looked around for an answer on this but nothing is springing back.

The data back looks like this (which is why the contract back is called "d" - not sure if that makes a difference or not, but the result is still the same, RespCode is 0, RespMess,Resp = string.Empty)

{ 
    "d":
    {
         "RespCode": 0,
         "RespMess": null,
         "Resp": null
    }
}

Upvotes: 0

Views: 215

Answers (1)

Tim S.
Tim S.

Reputation: 56536

Since your C# class properties (e.g. ResponseCode) and JSON names (e.g. RespCode) don't match, you need to specify those Names in your DataMember attributes. And the structure with the d could be represented by another class (I made ResponseClassContainer for it), not by simply naming the DataContract d. This works:

private string deserializeJSON(string resp, bool code = false)
{
    string value = string.Empty;
    ResponseClass deserialized = null;
    using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(resp)))
    {
        stream.Position = 0;
        var ser = new DataContractJsonSerializer(typeof(ResponseClassContainer));
        deserialized = (ser.ReadObject(stream) as ResponseClassContainer).d;
    }
    value = code ? deserialized.Response : deserialized.ResponseCode.ToString();
    return value;
}
[DataContract]
public class ResponseClassContainer
{
    [DataMember]
    public ResponseClass d { get; set; }
}
[DataContract]
public class ResponseClass
{
    [DataMember(Name="RespCode")]
    public int ResponseCode
    { get; set;}
    [DataMember(Name="RespMess")]
    public string ResponseMessage
    { get; set;}
    [DataMember(Name="Resp")]
    public string Response
    { get; set;}
}

The 0 integer and null strings were present because those are the default values for their respective types. Since the string didn't have any recognized data, those were all that were ever set there.

Upvotes: 1

Related Questions