1

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?

dbc
  • 104,963
  • 20
  • 228
  • 340
John Ohara
  • 2,821
  • 3
  • 28
  • 54
  • I have no control over what is in the string. – John Ohara Dec 18 '17 at 14:53
  • If you're working in c# 4.0 and so cannot use `UseSimpleDictionaryFormat` then possibly some of these answers would help: [Serialize `Dictionary` to JSON with DataContractJsonSerializer](https://stackoverflow.com/q/7498208/3744182). – dbc Dec 18 '17 at 22:01
  • But if not, can you switch to [tag:json.net] or even `JavaScriptSerializer`? Is use of `DataContractJsonSerializer` a requirement? – dbc Dec 18 '17 at 22:10

1 Answers1

1

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.

CodeFuller
  • 30,317
  • 3
  • 63
  • 79
  • This is the one and only instant I've used json - that's why I just wrote the extension. – John Ohara Dec 18 '17 at 14:49
  • I'm having trouble using the UseSimpleDictionaryFormat - showing an error. I'm using .Net 4.0 on this machine. – John Ohara Dec 18 '17 at 14:52
  • 1
    What is the error? Try using this code: `DataContractJsonSerializerSettings settings = new DataContractJsonSerializerSettings(); settings.UseSimpleDictionaryFormat = true;` – CodeFuller Dec 18 '17 at 14:54
  • I'm being told it's a syntax error - got the right reference and namespace. – John Ohara Dec 18 '17 at 14:59
  • It must be a version thing - cant see an overloaded constructor that includes settings – John Ohara Dec 18 '17 at 15:05
  • 1
    You're right, `DataContractJsonSerializerSettings` appeared only since 4.5 version of framework. Consider using Json.net if you can't upgrade. – CodeFuller Dec 18 '17 at 15:12