1
{
"Profile": {
    "dProperty1": {
        "a": "value",
        "b": "value",
        "c": "value",
        "d": "value",
        "e": "value"
    },
    "dProperty2": {
        "a": "value",
        "b": "value",
        "d": "value",
        "e": "value"
    },
    "dProperty3": {
        "a": "value",
        "b": "value",
        "d": "value",
        "e": "value"
       }
    }
}

I have a JSON object, which can have any number of dynamic properties. All the properties are objects that consist of mostly of the same fields. How can i parse this JSON into a strongly typed object in C#?

3
  • 1
    will they always stay the same name? It's a bit "unclean" but in the past I've created a class with all possible properties for the different variations, yet the JSON may not have all of them. It simply ignores the properties in the class that have no counterpart in the JSON. Commented Dec 10, 2015 at 13:04
  • 1
    Create type with all possible properties and deserealize JSON to it. Commented Dec 10, 2015 at 13:05
  • 1
    You can deserialize Profile as Dictionary<string, AbcdeClass> (where AbcdeClass contains superposition of properties from JSON) like for example here stackoverflow.com/questions/20727787/… Commented Dec 10, 2015 at 13:09

2 Answers 2

3

If you must have strongly typed result I would deserialize Profile as a dictionary of superposition of properties

class AbscdeClass
{
    public string A { get; set; }
    public string B { get; set; }
    public string C { get; set; }
    public string D { get; set; }
    public string E { get; set; }
}

class JsonBody
{
    public Dictionary<string, AbscdeClass> Profile { get; set; }
}

and parse original JSON text as

JsonBody json = JsonConvert.DeserializeObject<JsonBody>(jsonString);
Sign up to request clarification or add additional context in comments.

4 Comments

You say if i "must". Do you recommend another way?
You can use dynamic types (as in answer from @Jon Skeet). In case of your example I would go for dictionary with static types. If superposition class becomes too big and structureless or if the list of properties can evolve rapidly I would do dynamics. Since you explicitly stated that you need static types this reasoning was unnecessary
@Igor: I'm not using dynamic types. I'm parsing to a JObject, but I'm not using dynmamic typing anywhere, and I've still got a dictionary with a static type as the value too... Not that there's anything wrong with your approach either, mind you.
@Jon Skeet. My bad - I reacted too quick on JObject presence. The example of dynamic use of JObject.Parse can be found at stackoverflow.com/a/9326146/2413030
2

I would parse the whole tree as a JObject, and then call ToObject<> on appropriate sub-objects. Sample code:

using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json.Linq;

class Example
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var json = File.ReadAllText("test.json");
        var root = JObject.Parse(json);        
        var profile = (JObject) root["Profile"];
        var map = profile.Properties()
                         .ToDictionary(p => p.Name, p => p.Value.ToObject<Example>());
        foreach (var entry in map)
        {
            Console.WriteLine($"Key: {entry.Key}; Name: {entry.Value.Name}; Age: {entry.Value.Age}");
        }
    }
}

JSON:

{
  "Profile": {
    "dProperty1": {
      "name": "First",
      "age": 30,
      "extra": "Ignored"
    },
    "dProperty2": {
      "name": "Second",
      "age": 25
    },
    "dProperty3": {
      "name": "Third",
      "age": 50
    }
  }
}

Result:

Key: dProperty1; Name: First; Age: 30
Key: dProperty2; Name: Second; Age: 25
Key: dProperty3; Name: Third; Age: 50

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.