如何使用c#动态获取所有json元素?

时间:2018-06-04 16:03:32

标签: c# arrays json

我已关注json并使用c#class我已成功de-serialize但该怎么做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; }
    }

我可以从demo元素中获取值但是当有很多元素如a4,a5等我还没有添加到类中时?如何在不添加课程的情况下获得所有这些值?

  

我已经有课程,我不想修改如何   得到那些主要挑战的额外元素。

2 个答案:

答案 0 :(得分:3)

Json.net库中的JToken对象非常有用,您可以访问json对象和数组,而无需一组复杂的域模型类。当我必须访问复杂对象图的一些独立属性时,我使用它。我不想定义一大堆样板类,因此我可以访问几个属性。

当您不知道json如何或何时发生变化时,JToken类型也非常有用。保持课程层次更新可能会非常痛苦。

这里有一个很好的例子,说明JToken的用处: https://www.newtonsoft.com/json/help/html/QueryJsonSelectToken.htm

您可能已经有用于反序列化json的类,您仍然可以使用JToken作为期望json更改的属性。

将JTokens用于数据对象列表可以正常工作。

对于你的情况:

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>();

您也可以使用JToken.Parse进行整批操作,例如

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>();

调用SelectToken方法时,可以传递参数errorWhenNoMatch,以指示当属性/值不存在时是否应该抛出错误。这允许您在json数据具有未知结构时编写一些非常健壮的代码。

如果要枚举/遍历属性,可以执行以下操作:

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);

答案 1 :(得分: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