Search code examples
c#jsonserializationjson.netjson-deserialization

Serialise list of C# custom objects


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": "user2@email.com",
      "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


Solution

  • 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();