我正在使用一个 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
}
]}
我不想使用动态类型,我有我的类 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);
或类似的东西...
如果您知道在这种情况下要搜索什么 "d" 是一个根节点,那么您可以执行以下操作。
JObject jo = JObject.Parse(json);
DiskSpaceInfo[] diskSpaceArray = jo.SelectToken("d", false).ToObject<DiskSpaceInfo[]>();
如果您只是想忽略您不知道的根类,那么您可以使用"@Giu Do"解决方案,只是您可以使用test2.ToObject<DiskSpaceInfo[]>();
而不是Console.Write(test2);
JObject o = JObject.Parse(json);
if (o != null)
{
var test = o.First;
if (test != null)
{
var test2 = test.First;
if (test2 != null)
{
DiskSpaceInfo[] diskSpaceArray = test2.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>();
}
}
您将像这样调用它:
var resultA = JsonUtil.Deserialize<DiskSpaceInfo[]>(json, ignoreRoot: true);
或
var resultB = JsonUtil.Deserialize<DiskSpaceInfoRoot>(json, ignoreRoot: false);
通过 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。