skip to Main Content

Im in a situation where I am receiving Json that can be in two different formats and I am trying to find a good way to deserialize it into their respective objects. I have one Json string that would look like:

{
"Id": 1,
"Result": "true",
"Comment": "test comment"
}

And the other like:

{
"UserId": 12,
"PhoneNumber": "123456789",
"Message": "test message"
}

I had created an object that could hold both structures, something like:

public class EnvelopeObject
{
   public Structure1 { get; set; }
   public Structure2 { get; set; }
}

and ideally after deserializing the json into EvelopeObject I would have one object populated with the data from the json and the other would just be null. I know that this situation would require a custom converter, but after reading the documentation and looking for other examples, Im unsure how to go about this. Is there a simple custom converter solution, or an easier way to go about this?

2

Answers


  1. You could try and just deserialize both inner objects separately and set them to the Envelope Object. I believe that’s simple enough, no need for fancy custom conversion and deserialization.

    Here is the code snippet of the EnvelopeObject class and two sub classes:

    public class Json1Object
    {
        public string Id;
        public string Result;
        public string Comment;
    }
    
    public class Json2Object
    {
        public string UserId;
        public string PhoneNumber;
        public string Message;
    }
    
    public class EnvelopeObject
    {
        public Json1Object? Obj1 { get; set; }
        public Json2Object? Obj2 { get; set; }
    
        public bool IsJson1Object() => Obj1 is not null;
    }
    

    With the IsJson1Object() method you can check which one is set.

    And portion of the code where the EnvelopeObject class is being created (with added example strings):

    String json1 =
        """
        {
            "Id": 1,
            "Result": "true",
            "Comment": "test comment"
        }
        """;
    
    String json2 =
        """
        {
            "UserId": 12,
            "PhoneNumber": "123456789",
            "Message": "test message"
        }
        """;
    
    var json1Object = JsonConvert.DeserializeObject<Json1Object>(json1);
    var json2Object = JsonConvert.DeserializeObject<Json2Object>(json2);
    var envelopeObj = new EnvelopeObject
    {
        Obj1 = json1Object,
        Obj2 = json2Object
    };
    
    Login or Signup to reply.
  2. i create you example as another approach. call function which will return tuple of 2 classes, that which will match – would be populated. i use ID (first property) to identify which class to bind
    if you set jason as j2 or j1 you will get different class

    void Main()
    {
        var j1 = "{"Id":1,"Result":"true","Comment":"test comment"}";
        var j2 = "{"UserId":12,"PhoneNumber":"123456789","Message":"test message"}";
        
        string json = j2;
        
        GetClassSet(json).Dump();
    
        
        
    }
    
    public (Json1Object, Json2Object) GetClassSet(string json){
    
        using var doc = System.Text.Json.JsonDocument.Parse(json);
        object result = null;
        JObject res = (JObject)JsonConvert.DeserializeObject(json);
        if (res.First.ToObject<JProperty>().Name.ToUpper() == "ID")
        {
            return(res.ToObject<Json1Object>(), null);
        }
        else
        {
            return (null, res.ToObject<Json2Object>());
        }
    }
    
    public class Json1Object
    {
        public string Id;
        public string Result;
        public string Comment;
    }
    
    public class Json2Object
    {
        public string UserId;
        public string PhoneNumber;
        public string Message;
    }
    
    

    the results would be enter image description here
    or
    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search