Ameerudheen.K
Ameerudheen.K

Reputation: 667

JsonConvert Deserializer not converting nested json object

This is my JSON data:

{"condition":"OR","rules":[
  {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":7},
  {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":3},
  {"condition":"OR","rules":[
    {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":1},
    {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":7},
    {"condition":"OR","rules":[
      {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":7},
      {"id":94,"field":94,"type":"integer","input":"select","operator":"equal","value":20}
    ]}
  ]}
],"valid":true}

I am deserialing this with the following types, which I implemented according to multiple types in C# list:

public class QueryBuilderGroup
{
    public string Condition { get; set; }
    public List<QueryBuilderRules> Rules { get; set; }
    public bool? Valid { get; set; }
}

public class RulesInside : QueryBuilderRules
{
    public string Condition { get; set; }
    public List<QueryBuilderRules> Rules { get; set; }
}
public class QueryBuilderRule: QueryBuilderRules
{
    public int Field { get; set; }
    public int Id { get; set; }
    public string Input { get; set; }
    public string Operator { get; set; }
    public string Type { get; set; }
    public string Value { get; set; }
}

public class QueryBuilderRules {}

But here only the first level is getting deserialised and nested objects are just show as its type. Deserialised type

Can Anyone help?

Upvotes: 1

Views: 1359

Answers (3)

poke
poke

Reputation: 387677

public List<QueryBuilderRules> Rules { get; set; }

QueryBuilderGroup contains a list of QueryBuilderRules objects which is a type that contains no properties. So as far as the JSON deserializer is concerned, it does not have to actually deserialize anything in order to populate those objects.

The deserializer cannot know that you have two different subtypes RulesInside and QueryBuilderRule that have the right properties, which you expect to be materialized instead depending on which properties are set.

With Newtonsoft.Json, there are ways to make it able to deserialize different types but by default it will rely on a special structure in order to do that. You could also write a custom converter which would allow you to implement your own logic in order to serialize or deserialize those QueryBuilderRules objects. You can find a detailed example on how to implement this in this answer to a related question.

If you primarily want to consume this JSON data, what you could also do is to skip those types and instead use a combined type that has all the properties which may appear in those rules:

public class QueryBuilderRules
{
    public int Field { get; set; }
    public int Id { get; set; }
    public string Input { get; set; }
    public string Operator { get; set; }
    public string Type { get; set; }
    public string Value { get; set; }

    public string Condition { get; set; }
    public List<QueryBuilderRules> Rules { get; set; }
}

This basically just combines your RulesInside and QueryBuilderRule objects into a single one that can hold all of the information. When deserializing your JSON you may end up with a lot of null properties but when going over your data, you can then check for the existance of properties to determine which original type of rule this is.

Upvotes: 3

Krishna Varma
Krishna Varma

Reputation: 4260

Based on your json the model looks like below

public class Rule
{
    public int id { get; set; }
    public int field { get; set; }
    public string type { get; set; }
    public string input { get; set; }
    public string @operator { get; set; }
    public int value { get; set; }
    public string condition { get; set; }
    public List<Rule> rules { get; set; }
}

public class Root
{
    public string condition { get; set; }
    public List<Rule> rules { get; set; }
    public bool valid { get; set; }
}

I used Newtonsoft library to Deserialize the string

var json = File.ReadAllText("json.json");
var result = JsonConvert.DeserializeObject<Root>(json);

Upvotes: 1

Charly Guirao
Charly Guirao

Reputation: 489

You are using:

List<QueryBuilderRules> Rules

And should be

List<QueryBuilderRule> Rules

The class you are using as a base object doesn't have any properties. It doesn't make any sense to inherit from an empty class.

Upvotes: -1

Related Questions