0

I am receiving a JSON string from API that is structured in not a good way to be handled in the App.

I chose to create a custom serialiser for this JSON data (rather then having two different classes for data received and used in app).

Following a lot of tutorials I managed to put together a custom serialiser for a single object. However, I need to work with lists of these objects (there will be more different data that will come in these weird lists, that needs custom handling).

Is there a built in way I can set my custom serialiser to work with each object in the list? Or do I need to split the JSON object manually, and feed chunks of it to custom serialiser?

Any other suggestions how to handle this situation is appreciated.

User class:

[JsonConverter(typeof(UserSerializer))]
    public class User
    {
        public int id;
        public string displayName;
        public string email;
        public int total_points;
        public float total_values;
    }

The deserialiser:

public override object ReadJson(JsonReader reader, Type objectType, 
            object existingValue, JsonSerializer serializer)
        {
            JObject jObjectRoot = JObject.Load(reader);
            var root = jObjectRoot.Properties().ToList();
            JObject jObjectData = JObject.Load(root[2].Value.CreateReader());
            var data = jObjectData.Properties().ToList();
            return new User { 
                id = (int)root[1].Value,
                displayName = (string)data[0].Value,
                email = (string)data[1].Value,
                total_points = (int)data[2].Value,
                total_values = (float)data[3].Value
            };
        }

UPDATE:

Also the code that parses the json string to single user object:

public static void ProcessJSON(string json)
{
    User user = JsonConvert.DeserializeObject<User>(json);
}

And the JSON itself:

[
  {
    "type": "users",
    "id": 1,
    "attr": {
      "display_name": "user2",
      "email": "[email protected]",
      "total_points": 4,
      "total_values": 32.34
    },
    "relationships": {
      "points_received": {
        "links": {
          "self": "tipjar/users/1/relationships/points",
          "related": "tipjar/users/1/points"
        }
      },
      "points_given": {
        "links": {
          "self": "tipjar/users/1/relationships/awarded",
          "related": "tipjar/users/1/awarded"
        }
      }
    }
  }
]

Thanks

3
  • Have you looked at using Newtonsoft JSON.NET? Commented Oct 1, 2015 at 12:59
  • How does the JSON look? Commented Oct 1, 2015 at 13:02
  • @GlenThomas Yes, I am using Newtonsoft JSON.NET Commented Oct 1, 2015 at 13:04

2 Answers 2

2

You can get the list of user objects without a custom converter like this:

var userList = JArray.Parse(json)
    .Select(t => new User()
    {
        id = int.Parse(t["id"].ToString()),
        displayName = t["attr"]["display_name"].ToString(),
        email = t["attr"]["email"].ToString(),
        total_points = int.Parse(t["attr"]["total_points"].ToString()),
        total_values = float.Parse(t["attr"]["total_values"].ToString()),
    }).ToList();
Sign up to request clarification or add additional context in comments.

2 Comments

Lol this works like a charm, without writing complex converters. Thanks a lot :)
As a minor improvement, Json.Net supports casting JValues directly to their corresponding primitive types, so you can do total_points = (int)t["attr"]["total_points"] instead of using ToString() and then int.Parse()
-1
public static void ProcessJSON(string json)
{
    User u = new User();
    var test = JsonConvert.DeserializeObject(json);
    if (test.GetType() == typeof(User))
        u = (User)test;

}

Not 100% on how the serialize works, but this seemed to have worked on the test app I made.

It might be a bit silly. But you could test on the different types of objects returned...

2 Comments

Sorry, this will not work at all. If you don't specify a type in DeserializeObject then it will be a JToken of some kind, which is not a User. So the user u will always have default values. Even if you did specify User as a type argument to DeserializeObject, the JSON does not match up to the User class the OP has defined. Your answer does not show how to deal with this mismatch at all, nor how to handle a list of Users. That is the crux of the problem the OP is trying to solve here.
Back to the drawing board then. I'll do a bit more research into this. Thanks :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.