Search code examples
c#jsondatacontract

C# DataContract custom deserialisation


I need help with a DataContract problem. I have a web service that outputs JSON that needs to map to a C# object.

The important data returned from the API is wrapped in a "data" key of the JSON object but this is not important to me and I would like to discard it and have the JSON deserialised into the Item class. The Item class is used elsewhere and I would really like to leave it unchanged if possible.

Is there a way to change how data from the JSON is deserialised into the Item object but leave the Item object serialisation as default?

Currently the code is doing var item = await response.Content.ReadAsAsync<Item>(); to build the object from the API response.

If its not possible to leave the Item class unchanged then can you suggest the easiest modification to achieve the goal.

JSON:

{
  "data": {
    "id": "13c38fe9-6d9f-4a11-8eda-d071f2a99698",
    "item_type": 100,
    "item_name": "My Item Name"
  }
}

C# Object:

[DataContract]
public class Item
{
    [DataMember(Name = "id")]
    public Guid Id { get; set; }

    [DataMember(Name = "item_type")]
    public int? ItemType { get; set; }

    [DataMember(Name = "item_name")]
    public string ItemName { get; set; }
}

Any help would be greatly appreciated as C# is not normally a language I work with.


Solution

  • Based on your json, your data is coming in a format of a class like this

     [DataContract]
        public class Wrapper
        {
            [DataMember(Name = "data")]
            public Item item { get; set; }
        }
        [DataContract]
        public class Item
        {
            [DataMember(Name = "id")]
            public Guid Id { get; set; }
    
            [DataMember(Name = "item_type")]
            public int? ItemType { get; set; }
    
            [DataMember(Name = "item_name")]
            public string ItemName { get; set; }
        }
    

    Your response is in the format of a wrapper where data is an property of type Item. Add a wrapper to your contracts, it should work fine.

    You could run it like this, to check if your serialized string is in the same format.

    Wrapper tempData = new Wrapper() { item = new Item() {
                                                        Id = new Guid("13c38fe9-6d9f-4a11-8eda-d071f2a99698"),
                                                        ItemName = "My Item Name",
                                                        ItemType = 100 } };
        var serializedDta = JsonConvert.SerializeObject(tempData);