0

My application receives 2 JSON. One of which is:

{
  "topics": {
"test1": {
  "topic": "test1",
  "partitions": {
    "0": {
      "partition": 0,
      "next_offset": 8265537,
      "app_offset": 8265537,
      "stored_offset": 8265537,
      "commited_offset": 8265537,
      "committed_offset": 8265537,
      "eof_offset": 8265537,
      "lo_offset": 8261962,
      "hi_offset": 8265537,
      "consumer_lag": 0
    },
    "1": {
      "partition": 1,
      "next_offset": 9207622,
      "app_offset": 9207622,
      "stored_offset": 9207622,
      "commited_offset": 9207622,
      "committed_offset": 9207622,
      "eof_offset": 9207622,
      "lo_offset": 9203938,
      "hi_offset": 9207622,
      "consumer_lag": 0
    },
    "2": {
      "partition": 2,
      "next_offset": 7954425,
      "app_offset": 7954425,
      "stored_offset": 7954425,
      "commited_offset": 7954425,
      "committed_offset": 7954425,
      "eof_offset": 7954425,
      "lo_offset": 7950785,
      "hi_offset": 7954425,
      "consumer_lag": 0
      }
     }
   }
 }
  }

And the other is test2 with "topic" as "test2". And the topic name differentiates both the JSON.

One way I basically converted it into dynamic object and loop through the JSON. But I want to create one common class for both JSON to convert it into. My only confusion is how can create a generic class to deserialize both the JSON.

Because right now I am creating two classes like :

 public class Root
 {
   public Topics topics { get; set; }
 }

 public class Topics
 {
    public Test1 test1 { get; set; }
 }

 public class Test1
 {
   public string topic { get; set; }
   public Partitions partitions { get; set; }
 }

And same way for test2.

Any help?

10
  • 2
    if you don't know in advance what the JSON structure is going to be, then you can't specify a concrete type you want to deserialise it to. I'm not sure you can realistically do this. Are the structures of the "test1" and "test2" objects very different? Commented May 10, 2019 at 8:27
  • 1
    Do the "1", "2" and "3" have various differing fields - the last and the first two seem to differ. Is that always the case? Are there always 3, or a varying number, like some kind of Array or List? Commented May 10, 2019 at 8:27
  • @doctorlove: No fields in Partition will not differ only the Root Topic Name will change either test1 or test2 Commented May 10, 2019 at 8:30
  • Also, have you got any control over the JSON you're receiving? Is it coming from some code you wrote, or can influence? This isn't a brilliant structure - as doctorlove is hinting, it might make more sense for "Partitions" to be an array rather than a list of items with numbered keys. Also if we can see "test2"'s structure, for comparison, maybe we could see a way to merge them into a single type. Commented May 10, 2019 at 8:30
  • 1
    We would need to know the schema of the JSON you are going to receive to give a proper answer. for example, are the values always Test1 and Test2 or will they be random? How many will there be? Why does partition 2 not have a partition property etc. Commented May 10, 2019 at 8:34

2 Answers 2

1

I'd suggest using Dictionary<> types for keys that will change like the test1 value and the partition numbers. For example, something like this should work well:

public class Root
{
    public Dictionary<string, Test> Topics { get; set; }
}

public class Test
{
    public string Topic { get; set; }
    public Dictionary<int, Partition> Partitions { get; set; }
}

public class Partition
{
    [JsonProperty("partition")]
    public int PartitionNo { get; set; }
    [JsonProperty("next_offset")]
    public int NextOffset { get; set; }

    // etc...
}

And deserialise with:

var result = JsonConvert.DeserializeObject<Root>(Json);
Sign up to request clarification or add additional context in comments.

Comments

0

List Sample: - JSON object & class object like below:

    {
      "topics":[{
        "topic":"test1",
        "partition":{...}
        },{
        "topic":"test2",
        "partition":{...}
       }]
    }


    class Root
    {
        public List<Topics> topics { get; set; }
    }
    class Topics
    {
        public string topic { get; set; }
        public Partitions partitions { get; set; }
    }

Specify Sample: - JSON object & class object like below:

    {
      "topics":{
        "test1":{
        "topic":"test1",
        "partition":{...}
        },
        "test2":{
        "topic":"test2",
        "partition":{...}
       }]
    }

    class Root
    {
        public Test topics{ get; set; }
    }
    class Test{
        public Topics test1{get;set;} 
        public Topics test2{get;set;} 
    }
    class Topics
    {
        public string topic { get; set; }
        public Partitions partitions { get; set; }
    }

3 Comments

One way to be able to call it into a generic code is to create a [JsonIgnore] or equivalent property that return either test1 or test2 (the one not null).
@Andy: At one point in time we can have only one Topic. So do we need a list? And in case of 2 properties which property it will set at the time of deserializing since we will have only one topic? And how to deal with multiple partitions. You have created only a Partition class but how can it represent values of partitions 0 to 1 along with its properties like offset?
@JacobHigs I misunderstand this question, sorry for that and I will be more cautious. And DavidG 's answer is better

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.