Gold.strike
Gold.strike

Reputation: 1287

Deserialize a Json containing a list of object

I work on an UniversalApp that call a lot of webservices returning JSON datas.

All the webservices return me a first level of Json (WsResponse.cs), that contained this structure:

public string status { get; set; }
public object data { get; set; }
public List<object> errors { get; set; }

If the status is "success", I can deserialize the simple data object by:

WsResponse wsResponse = JsonConvert.DeserializeObject<WsResponse>(response);    
User user = JsonConvert.DeserializeObject<User>(wsResponse.data.ToString());

In other cases, it is necessary to deserialize first in a result object, before to deserialize the datas:

WsResponse wsResponse = JsonConvert.DeserializeObject<WsResponse>(response);
WsResponseResult wsResponseResult = JsonConvert.DeserializeObject<WsResponseResult>(
                                                            wsResponse.data.ToString());
List<Theme> themes = JsonConvert.DeserializeObject<List<Theme>>(
                                                    wsResponseResult.result.ToString());

But if the status is "failure", I need to catch the errors list. But I can't deserialize this object list... Here is an example of JSON datas that I get from webservice when it contains errors:

{
  "status": "failure",
  "data": {},
  "errors": [
    {
      "200": "The parameter 'email' is not present"
    },
    {
      "200": "The parameter 'password' is not present"
    }
  ]
}

I try to deserialize it by:

List<KeyValuePair<string, string>> kvpError = new List<KeyValuePair<string,string>>();
kvpError = JsonConvert.DeserializeObject<List<KeyValuePair<<string, string>>>(
                                                            wsResponse.errors.ToString());

Dictionary<string, string> dError = new Dictionary<string, string>();
dError = JsonConvert.DeserializeObject<Dictionary<string, string>>(
                                                            wsResponse.errors.ToString());

=> but it doesn't work

I also try to through the error datas before deserializing them:

foreach(var error in wsResponse.errors)
{                        
    KeyValuePair<string, string> kvpError = new KeyValuePair<string,string>();
    kvpError = JsonConvert.DeserializeObject<KeyValuePair<string, string>>(
                                                                        error.ToString());
}

=> but it doesn't work better...

Would you have an idea on how to solve my problem?

Upvotes: 1

Views: 1425

Answers (1)

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

The way your JSON is structured, errors is actually a List<Dictionary<string, string>>. If you use that instead of List<object>, it will deserialize the errors properly:

public class Response
{
    public string status { get; set; }
    public object data { get; set; }
    public List<Dictionary<string, string>> errors { get; set; }
}

Yields:

Deserialization result

Side note - If you have any control of the JSON structure, you're better off with a single List<KeyValuePair<string, string>> which you can deserialize. Also, instead of using object data, actually pass the User properties inside the JSON so you can save yourself the double deserialization.

If you wanted to make it possible to deserialize this to a List<KeyValuePair<string, string>>, your JSON would need to look like this:

{
  "status": "failure",
  "data": {},
  "errors": [
    {
      "Key": "200", "Value": "The parameter 'email' is not present"
    },
    {
      "Key": "200", "Value": "The parameter 'password' is not present"
    }
  ]
}

Upvotes: 1

Related Questions