John Ohara
John Ohara

Reputation: 2901

Json Deserializing not populating properties

I'm deserializing a third party string like this:

{"status":4,"errors":[{"Duplicate Application":"Duplicate Application"}]}

I use my standard extension method:

public static T DeserializeJson<T>(string response)
    where T : class
{
    var s = new DataContractJsonSerializer(typeof(T));

    try {
        using (var ms = new MemoryStream()) {
            byte[] data = System.Text.Encoding.UTF8.GetBytes(response);
            ms.Write(data, 0, data.Length);
            ms.Position = 0;

            return (T)s.ReadObject(ms);
        }
    }
    catch {
        return default(T);
    }
}

The class I'm trying to deserialize to looks like this:

[DataContract]
public class ResponseProps
{
    [DataMember(Name = "status", Order = 0)]
    public string ResponseCode { get; set; }

    [DataMember(Name = "lead_id", Order=1)]
    public string LeadId { get; set; }

    [DataMember(Name = "price", Order=2)]
    public decimal Price { get; set; }

    [DataMember(Name = "redirect_url", Order = 3)]
    public string RedirectUrl { get; set; }

    [DataMember(Name = "errors", Order = 4)]
    public List<Dictionary<string, string>> Errors { get; set; }
}

I'm using a List of type Dictionary (string, string) for the Errors property because other types I've tried have broken the deserializer - this works in that the serializer no longer throws an exception.

However, I'm now trying to retrieve the data from Errors - I'm using this code:

var cr = XmlHelper.DeserializeJson<ResponseProps>(response);             

    var errorStore = new HashSet<string>();

    foreach (var dict in cr.Errors)
    {
        foreach (var kvp in dict)
        {
            errorStore.Add(kvp.Key + ": " + kvp.Value);
        }
    }

I've done various tests - the dict counts 1, but there are no kvp, so when the loop runs I get no messages.

I'm guessing this is again down to deserialization rather than incorrect looping, but I've not been able to fix it.

Anyone got any advice?

Upvotes: 1

Views: 1216

Answers (1)

CodeFuller
CodeFuller

Reputation: 31312

To be able to deserialize such dictionary, you should customize settings of DataContractJsonSerializer with UseSimpleDictionaryFormat set to true:

DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings
{
    UseSimpleDictionaryFormat = true
};
var s = new DataContractJsonSerializer(typeof(T), settings);

By the way, do you have any reason to use DataContractJsonSerializer with your custom DeserializeJson<T>() method? You could do the same in one line of code with JSON.Net:

var obj = JsonConvert.DeserializeObject<ResponseProps>(str);

JSON.Net is also much more flexible and have a better performance than DataContractJsonSerializer.

Upvotes: 1

Related Questions