0

I have following json and using c# class i have de-serialize it successfully but how to do it dynamically without adding property into c# class ?

"demo": [
      {
        "a1": 1,
        "a2": 32,
        "a3": 100,
        "a4": 344,
        "a5": 455,
        "data": [
          {

          }
        ]
      }
      ]




public class demo
    {
        [JsonProperty(PropertyName = "a1")]
        public int? a1 { get; set; }
        [JsonProperty(PropertyName = "a2")]
        public int? a2 { get; set; }
        [JsonProperty(PropertyName = "a3")]
        public int? a3 { get; set; }
        [JsonProperty(PropertyName = "data")]
        public List<data> data { get; set; }
    }

i can able to get values from demo element but when there are many elements like a4,a5 and so on that I have not added into class ? how can i get all those values without adding into class ?

I already have classes present and i do not want to modify that how to get then extra elements that is main challenge.

Neo
  • 15,491
  • 59
  • 215
  • 405
  • 1
    Possible duplicate of [Deserialize JSON into C# dynamic object?](https://stackoverflow.com/questions/3142495/deserialize-json-into-c-sharp-dynamic-object) –  Jun 04 '18 at 16:06
  • This is using Newtonsoft JSON.Net? Do you have to deserialize to a concrete object - could you deserialize to a dictionary or a dynamic instead? Your JSON deserializer might also support a catch-all property or a callback for unrecognised values that you can trap and record too. – Rup Jun 04 '18 at 16:07
  • i can use newtonsoft,JSON = – Neo Jun 04 '18 at 16:08

2 Answers2

3

The JToken object in the Json.net library is very useful, you can access json objects and arrays without needing a complex set of domain model classes. I use it when I have to access a few isolated properties of a complex object graph. I don't want to define a whole load of boilerplate classes just so I can access a couple of properties.

The JToken type is also very useful when you don't know how or when the json might change. Keeping a class hierarchy up to date can be very painful.

There's a good example of the usefulness of JToken here: https://www.newtonsoft.com/json/help/html/QueryJsonSelectToken.htm

You may already have classes that you use to deserialize json, you can still use JToken as properties where you expect the json to change.

Using JTokens for the Data object list would work.

For your case:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class demo
{
    [JsonProperty(PropertyName = "a1")]
    public int? a1 { get; set; }
    [JsonProperty(PropertyName = "a2")]
    public int? a2 { get; set; }
    [JsonProperty(PropertyName = "a3")]
    public int? a3 { get; set; }
    [JsonProperty(PropertyName = "data")]
    public List<JToken> data { get; set; }
}

var json = @"{
          ""a1"": 10,
          ""a2"": 11,
          ""a3"": 13,
          ""uuid"": ""1c18f0c8-02d0-425a-8dc7-13dc6d0b46af"",
          ""data"": [
            {
              ""id"": 1,
              ""timeStamp"": ""2018-01-03T08:01:00Z"",
              ""quantity"": 200.0,
              ""tag"": ""/sometag/""
            },
            {
              ""id"": 2,
              ""timeStamp"": ""2018-01-03T08:05:00Z"",
              ""quantity"": 100.0,
              ""tag"": ""/someothertag/""
            },
            {
            ""id"": 3,
              ""name"": ""somename"",
              ""age"": 32
            }
          ]
        }";


var demo1 = JsonConvert.DeserializeObject<demo>(json);

// Let's get the timeStamp of item 2.
var timeStamp = demo1.data[1].SelectToken("timeStamp").ToObject<DateTime>();

// Let's get the age of item 3.
var age = demo1.data[2].SelectToken("age").ToObject<int>();

You can also make use of JToken.Parse for the whole lot, e.g.

var obj1 = JToken.Parse(json);

// Get a1
var a1 = obj1.SelectToken("a1", false).ToObject<int>();

// Get uuid
var uuid = obj1.SelectToken("uuid", false).ToObject<Guid>();

// Let's get the timeStamp of item 2.
var timeStamp = obj1.SelectToken("data[1].timeStamp").ToObject<DateTime>();

// Let's get the age of item 3.
var age = obj1.SelectToken("data[2].age").ToObject<int>();

When calling the SelectToken method, you can pass the parameter errorWhenNoMatch to indicate whether an error should be thrown when the property/value does not exist. This allows you to write some very robust code when the json data is of an unknown structure.

If you want to enumerate/traverse properties you can do something like this:

static void TraverseProperties(JToken jtoken)
{
    foreach (var value in jtoken.Values())
    {
        if (!value.HasValues)
        {
            Console.WriteLine(value.Path + ": " + value.ToObject<string>());
        }
        else
        {
            TraverseProperties(value);
        }
    }
}

TraverseProperties(obj1);
Terry Lennox
  • 29,471
  • 5
  • 28
  • 40
2

i do not think you can do that. however you can try following. however im not quite sure that you will get intellisense assistance or not.

using System.Web.Script.Serialization;

JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
var deserializedContet = javaScriptSerializer.Deserialize<dynamic>(yourJsonString);

check this out

https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.100).aspx

charith rasanga
  • 124
  • 2
  • 3