Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化JSON-如何忽略根元素?_C#_.net_Deserialization_Json.net - Fatal编程技术网

C# 反序列化JSON-如何忽略根元素?

C# 反序列化JSON-如何忽略根元素?,c#,.net,deserialization,json.net,C#,.net,Deserialization,Json.net,我正在使用一个WCF服务,该服务返回包装在“d”根元素中的JSON结果。JSON响应如下所示: {"d":[ { "__type":"DiskSpaceInfo:#Diagnostics.Common", "AvailableSpace":38076567552, "Drive":"C:\\", "TotalSpace":134789197824 }, { "__type":"DiskSpaceInfo:#Diagnostics.Common"

我正在使用一个WCF服务,该服务返回包装在“d”根元素中的JSON结果。JSON响应如下所示:

{"d":[
  {
    "__type":"DiskSpaceInfo:#Diagnostics.Common",
    "AvailableSpace":38076567552,
    "Drive":"C:\\",
    "TotalSpace":134789197824
  },
  {
    "__type":"DiskSpaceInfo:#Diagnostics.Common",
    "AvailableSpace":166942183424,
    "Drive":"D:\\",
    "TotalSpace":185149157376
  }
]}
var resultA = JsonUtil.Deserialize<DiskSpaceInfo[]>(json, ignoreRoot: true);
我不想使用动态类型,我有我的类Diagnostics.Common.DiskSpaceInfo,我想在反序列化时使用它

我使用的是Json.NET(Netwonsoft Json)

问题是如何告诉它忽略根元素(“d”元素)并解析其中的内容

到目前为止,我拥有的最佳解决方案是使用匿名类型:

DiskSpaceInfo[] result = JsonConvert.DeserializeAnonymousType(json, new
    {
        d = new DiskSpaceInfo[0]
    }).d;
这确实有效,但我不太喜欢。还有别的办法吗?我想要的是:

DiskSpaceInfo[] result = JsonConvert.Deserialize(json, skipRoot: true);

或者类似的东西…

由Newtonsoft提供,我想您使用的是JSon.net,这是我的解决方案,我使用了此框架中可用的Linq to JSon:

using System;
using Newtonsoft.Json.Linq;

namespace JSonTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"{""d"":[
  {
    ""__type"":""DiskSpaceInfo:#Diagnostics.Common"",
    ""AvailableSpace"":38076567552,
    ""Drive"":""C:\\"",
    ""TotalSpace"":134789197824
  },
  {
    ""__type"":""DiskSpaceInfo:#Diagnostics.Common"",
    ""AvailableSpace"":166942183424,
    ""Drive"":""D:\\"",
    ""TotalSpace"":185149157376
  }
]}";
        JObject o = JObject.Parse(json);

        if (o != null)
        {
            var test = o.First;

            if (test != null)
            {
                var test2 = test.First;
                if (test2 != null)
                {
                    Console.Write(test2);
                }
            }
        }

        Console.Read();

    }
}
}
我使用了属性First,因为您需要找到d之后的第一个节点,这是您收到的json的第一个节点


您只需要创建一个函数来重新编译Main,不要忘记检查对象是否为null,以避免出现NullReferenceException

如果您知道在这种情况下搜索什么,例如“d”,它是根节点,那么您可以执行以下操作

JObject jo = JObject.Parse(json);
DiskSpaceInfo[] diskSpaceArray = jo.SelectToken("d", false).ToObject<DiskSpaceInfo[]>();

根据前面的答案,我建议您使用自己的静态实用程序类。这是可重用的,并允许您获得所需的语法

public static class JsonUtil
{
    public static T Deserialize<T>(string json, bool ignoreRoot) where T : class
    {
        return ignoreRoot 
            ? JObject.Parse(json)?.Properties()?.First()?.Value?.ToObject<T>()
            : JObject.Parse(json)?.ToObject<T>();
    }
}
公共静态类JsonUtil
{
公共静态T反序列化(字符串json,bool ignoreRoot),其中T:class
{
返回信号根
?JObject.Parse(json)?.Properties()?.First()?.Value?.ToObject()
:JObject.Parse(json)?.ToObject();
}
}
您可以这样调用它:

{"d":[
  {
    "__type":"DiskSpaceInfo:#Diagnostics.Common",
    "AvailableSpace":38076567552,
    "Drive":"C:\\",
    "TotalSpace":134789197824
  },
  {
    "__type":"DiskSpaceInfo:#Diagnostics.Common",
    "AvailableSpace":166942183424,
    "Drive":"D:\\",
    "TotalSpace":185149157376
  }
]}
var resultA = JsonUtil.Deserialize<DiskSpaceInfo[]>(json, ignoreRoot: true);
var resultA=JsonUtil.Deserialize(json,ignoreRoot:true);

var resultB=JsonUtil.Deserialize(json,ignoreRoot:false);

+1因为我喜欢您的匿名类型解决方案。相关问题询问如何在不解析到中间
JToken
的情况下执行此操作。感谢Giu do提供Json.NET命名,我在原始问题中对其进行了编辑。关于您的解决方案,我如何将test2转换为正确的DiskSpaceInfo类型?test2仍然是JToken类型。谢谢!不错的解决方案,我试过了,效果不错。如果有人提出不同的方法,我会让这个主题保持开放状态,然后我会把你的作为这个主题的答案。然而,没有一种解决方案能让我产生一种强烈的感觉,比其他解决方案更喜欢它(包括我最初的匿名类型方法)。也许我可以做一些基准测试,看看这三种方法中的一种是否对性能有好处。