Home > Net >  Json with data inconsistency
Json with data inconsistency

Time:10-08

I got this strange API response from one external service:

{emplooye: "Michael",age:"25",attachments:[{idAttachment: "23",attachmentPath:"C://Users/1"},{idAttachment: "24",attachmentPath:"C://Users/2"}]},{emplooye: "John",age:"30",attachments:{idAttachment: "25",attachmentPath:"C://Users/3"}}

Has anyone ever faced a situation where sometimes the "Attachment" property can be an array, sometimes it can be an object? I created a class to manipulate the data, but when I find an object, the code breaks. I'm doing this in C#.

Class Used

public class Attachments
    {
        public string idAttachment{ get; set; }
        public string attachmentPath{ get; set; }
    }

public class Root
{
    public string emplooye {get; set;}
    public string age {get;set}
    public List<Attachments> attachments { get; set; } = new List<Attachments>();
}

CodePudding user response:

your json is not even close to json, should be something like this

var json = "[{\"emplooye\":\"Michael\",\"age\":\"25\",\"attachments\":[{\"idAttachment\":\"23\",\"attachmentPath\":\"C://Users/1\"},{\"idAttachment\":\"24\",\"attachmentPath\":\"C://Users/2\"}]},{\"emplooye\":\"John\",\"age\":\"30\",\"attachments\":{\"idAttachment\":\"25\",\"attachmentPath\":\"C://Users/3\"}}]";

Using Newtonsoft.Json you can create a JsonConstructor

using Newtonsoft.Json;

List<Data> data= JsonConvert.DeserializeObject<List<Data>>(json);
 

public class Data
{
    public string emplooye { get; set; }
    public string age { get; set; }
    public List<Attachments> attachments { get; set; }

    [JsonConstructor]
    public Data(JToken attachments)
    {
        attachments.Type.ToString().Dump();
        if (attachments.Type.ToString() == "Array") 
            this.attachments = attachments.ToObject<List<Attachments>>();
        else
            this.attachments = new List<Attachments> { attachments.ToObject<Attachments>() };
    }
    public Data() {}
}

public class Attachments
{
    public string idAttachment { get; set; }
    public string attachmentPath { get; set; }
}

CodePudding user response:

You can use Newtonsoft to parse to a JToken which will handle the typing for you, but with the downside of not having a stable and predictable class to deserialize to automatically

Then, you would want to check its type, which returns a JTokenType enum

Once you know what the underlying types are, marshal the data into your DTO classes

JToken responseJT = JToken.Parse(json); //json string

if (responseJT.Type == JTokenType.Array)
    //its an array, handle as needed ...
else if (responseJT.Type == JTokenType.Object)
    //its an object, handle as needed ...

Personally, I would keep the attachments property as a List<Attachments> and if the JToken has a JSON object I would just set it as the [0] index of that property. This way things stay consistent and you can use LINQ on that property with ease

  • Related