【问题标题】:How to tell if JSON result has object or array?如何判断 JSON 结果是否有对象或数组?
【发布时间】:2014-12-03 21:13:44
【问题描述】:

对不起各位。我对编写代码很陌生...

我正在用 c# 编写一个 powershell cmdlet,它会访问 API 并获取 JSON 作为响应。

根据我对 API 的调用,返回一个 JSON 数组或单个 JSON 对象

有时候,可以

{"result": [
{
"id": "24095",
"hostid": "24094",
"name": "host1.fqdn.com",
"clustered": "false",
"type": "VM",
"ipaddress" : "192.168.1.184"
},
{
"id": "24097",
"hostid": "24096",
"name": "host2.fqdn.com",
"clustered": "true",
"type": "VM",
"ipaddress" : "192.168.1.185"
}
]
}

有时可以

{"result": {
"id": "24095",
"hostid": "24094",
"name": "host1.fqdn.com",
"clustered": "false",
"type": "VM",
"ipaddress" : "192.168.1.184"
}
}

我试图弄清楚如何使用 JSON.NET,我可以弄清楚返回的 json 是否有一个用于“结果”的对象或一个用于“结果”的数组。

根据检查,我想调用一个方法,以 CSV 格式打印出对象或数组

我希望编写一个通用方法,将所有键打印为 CSV 标头,将值打印为 CSV 的行。

但我遇到的第一件事是弄清楚我的 JSON 对象是有一个数组还是只有一个对象

我试过了

JObject jsonres = JObject.Parse(strResponse);
JObject appobj = (JObject)jsonres.SelectToken("result");

Console.WriteLine(appobj.Type.ToString());

结果

无法将类型为“Newtonsoft.Json.Linq.JArray”的对象转换为类型 'Newtonsoft.Json.Linq.JObject'。

当 appobj["result"] 是一个数组并且工作正常并且当 appobj["result"] 是单个对象时打印 "Object"。

【问题讨论】:

    标签: c# json linq


    【解决方案1】:

    不确定这是否是处理它的最佳方法,但您可以使用以下方法:

    if ( jsonres.SelectToken("result") is JObject )
    { ... }
    else if ( jsonres.SelectToken("result") is JArray)
    { ... }
    else
    { ...some exception perhaps }
    

    编辑:轻微的即兴创作

    if ( jsonres.SelectToken("result") is JObject )
    { //Create JArray with the lone "result" in it }
    
    //Use the JArray 
    

    【讨论】:

    • 哦!甜的!这让它变得容易多了!非常感谢@bit。
    【解决方案2】:

    这将起作用:

       JObject jsonres = JObject.Parse(json);
       Console.WriteLine(jsonres["result"].Type);
    

    判断它是对象还是数组。您可以在枚举上使用 switch-case:

                switch(jsonres["result"].Type)
                {
                    case JTokenType.Object:
                   //Do something if it's an object
                        break;
                    case JTokenType.Array:
                    //Do something if it's an array
                        break;
                }
    

    【讨论】:

    • 谢谢。这也是一个不错的选择!
    【解决方案3】:

    这是一个相当老的问题,但如果您不想使用 Newtonsoft.Json 命名空间,我已经得到了 System.Text.Json 命名空间的答案。 JsonDocument 中还有一个 Parse 方法,您可以在其中确定根元素的类。

    var JDocument = System.Text.Json.JsonDocument.Parse(json);
    if (JDocument.RootElement.ValueKind == JsonValueKind.Object)
    {
        //Object
    }
    
    if (JDocument.RootElement.ValueKind == JsonValueKind.Array)
    {
        //Array or List
    }
    

    【讨论】:

      【解决方案4】:

      您可以为此创建 JsonConverter,例如

      public class SingleOrListJsonConverter : JsonConverter
      {
          public override bool CanWrite => false;
      
          public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
          {
              throw new NotImplementedException();
          }
      
          public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
          {
              var token = JToken.ReadFrom(reader);
              switch (token.Type)
              {
                  case JTokenType.Object:
                      var item = token.ToObject<MyResultType>();
                      return new List<MyResultType>(new[] {item});
                  case JTokenType.Array:
                      return token.ToObject<List<MyResultType>>();
                  default:
                      return new List<MyResultType>();
              }
          }
      
          public override bool CanConvert(Type objectType)
          {
              return objectType == typeof(List<MyResultType>) || objectType == typeof(MyResultType);
          }
      }
      

      然后用这个转换器装饰你的财产

      public class MyClass
      {
          [TypeConverter(typeof(SingleOrListJsonConverter))]
          public MyResultType Result { get; set; }
      }
      

      我想我们甚至可以使这个转换器通用,但这只是一个简单的例子。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-29
        相关资源
        最近更新 更多