Deserialize JSON object into nested C# object Deserialize JSON object into nested C# object json json

Deserialize JSON object into nested C# object


You can do this using a custom JsonConverter.

public class CustomerJsonConverter : JsonConverter{    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)    {        if (value is Customer customer)        {            var token = new JObject            {                ["id"] = customer.Id,                ["userName"] = customer.UserName,                ["address"] = customer.Address.Address,                ["address2"] = customer.Address.Address2,                ["city"] = customer.Address.City,                ["state"] = customer.Address.State,                ["zip"] = customer.Address.ZIP            };            token.WriteTo(writer);        }        else        {            throw new InvalidOperationException();        }    }    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)    {        var obj = JToken.ReadFrom(reader);        if (obj.Type != JTokenType.Object)        {            return null;        }        return new Customer        {            Id = (long) obj["id"],            UserName = (string) obj["userName"],            Address = obj.ToObject<AddressModel>()        };    }    public override bool CanRead => true;    public override bool CanConvert(Type objectType)    {        return objectType == typeof(Customer);    }}

Along with a JsonConverterAttribute on the Customer class.

[JsonConverter(typeof(CustomerJsonConverter))]public class Customer{    public long Id { get; set; }    public string UserName { get; set; }    public AddressModel Address { get; set; }}public class AddressModel{    public string Address { get; set; }    public string Address2 { get; set; }    public string City { get; set; }    public string State { get; set; }    public string ZIP { get; set; }}

And utilize as such:

var customer = JsonConvert.DeserializeObject<Customer>(customerJson);

alternatively, you could simply have an intermediate mapping model.

public class CustomerFlattened{    public long Id { get; set; }    public string UserName { get; set; }    public string Address { get; set; }    public string Address2 { get; set; }    public string City { get; set; }    public string State { get; set; }    public string ZIP { get; set; }    public Customer ToCustomer()    {        return new Customer        {            Id = Id,            UserName = UserName,            Address = new AddressModel            {                Address = Address,                Address2 = Address2,                City = City,                State = State,                ZIP = ZIP            }        };    }    public static CustomerFlattened FromCustomer(Customer customer)    {        return new CustomerFlattened        {            Id = customer.Id,            UserName = customer.UserName,            Address = customer.Address.Address,            Address2 = customer.Address.Address2,            City = customer.Address.City,            State = customer.Address.State,            ZIP = customer.Address.ZIP        };    }}

And utilize as such:

var customer =    JsonConvert.Deserialize<CustomerFlattened>(        jsonOriginal    )    .ToCustomer();var customerFlattened = CustomerFlattened.FromCustomer(customer);var jsonConverted = JsonConvert.Serialize(customerFlattened );


If you're the one setting up the JSON that'll be consumed by your code, then your JSON is not setup to match your object.

It should look like this:

{    "id": 123,    "userName": "fflintstone",    "address": {        // address properties here    }} 

Otherwise you need to update your C# object to match the JSON, which would mean individual properties for each item in the JSON:

public class Customer{    public long Id { get; set; }    public string UserName { get; set; }    public string Address { get; set; }    public string Address2 { get; set; }    public string City { get; set; }    public string State { get; set; }    public string ZIP { get; set; }}

Further, if you're setting up both of these, the street name probably shouldn't be named "Address". To me, the word "address" means the street name, number, city, state, and ZIP as one whole thing.

If you don't have control over the JSON, then there's no real way to cleanly deserialize the JSON into your object with something like Json.Net. You'll need to set up some sort of mapper, or look for the properties directly to obtain their values to add them to your object. You can parse the JSON into a JObject, then access the properties you need.

JObject foo = JObject.Parse(//your JSON string here);customer.Address = (string)foo["Address"];customer.Address2 = (string)foo["Address2];

In general, if you're not the one in control of the JSON structure, it's probably best to just make your objects match the JSON you're given.


If you're willing to use an additional tool, you can create a DTO that matches the JSON and then use a mapper like Automapper to reverse flatten the DTO into your object model.