1

I have for example these classes

public class JsonResult
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("myobjects")]
    public List<BaseClass> myObjects { get; set; }
}

public abstract class BaseClass
{
    [JsonProperty("name")]
    public string Name { get; set; }
}

public class FlavourOne: BaseClass
{
    [JsonProperty("number")]
    public int Number { get; set; }
    [JsonProperty("mytext")]
    public string MyText { get; set; }
}

public class FlavourTwo: BaseClass
{
    [JsonProperty("yourtext")]
    public string YourText { get; set; }
}

And i have this Json object coming in as a string

{
"name": "examplename",
"myobjects": [
    {
        "name": "myFlavourOneInstance",
        "number": 1,
        "mytext": "Text from One"
    },
    {
        "name": "myFlavourTwoInstance",
        "yourtext": "Your Text from Two"
    }
]
}

I would like to have an object from that Json string as follows

var responseObject = JsonConvert.DeserializeObject<JsonResult>(rawJsonString);

But this does not work, is there a nice and clean way to have the json into the object with inherited classes and so on?

1 Answer 1

3

Yes, you can specify the class in the Json for deserialization using TypeNameHandling.Auto (or TypeNameHandling.All, depending on your use case).

Here's an example using TypeNameHandling.Auto:

void Main() {
    var jsonResult = new JsonResult {
        Name = "test",
        myObjects = new List<BaseClass> {
            new FlavourOne {
                Name = nameof(FlavourOne),
                Number = 1,
                MyText = "Text from one" 
            },
            new FlavourTwo {
                Name = nameof(FlavourTwo),
                YourText = "Text from two"
            }
        }
    };
    
    var serializerSettings = new JsonSerializerSettings {
       TypeNameHandling = TypeNameHandling.Auto
    };

    var json = JsonConvert.SerializeObject(jsonResult, Formatting.Indented, serializerSettings);
    
    Console.WriteLine(json);
}

// Your classes here

Output:

{
  "name": "test",
  "myobjects": [
    {
      "$type": "FlavourOne, AssemblyName",
      "number": 1,
      "mytext": "Text from one",
      "name": "FlavourOne"
    },
    {
      "$type": "FlavourTwo, AssemblyName",
      "yourtext": "Text from two",
      "name": "FlavourTwo"
    }
  ]
}

This means that when deserialized, they are assigned the correct type, as long as you use the same serializer settings:

var responseObject = JsonConvert.DeserializeObject<JsonResult>(json, serializerSettings);

Note though, as per the docs:

TypeNameHandling should be used with caution when your application deserializes JSON from an external source.

This is because you don't want to let external Json create arbitrary types!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.