'd'ルート要素内にラップされたJSON結果を返すWCFサービスを使用しています。 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[]>();
わからないルートクラスを単に無視したい場合は、test2.ToObject<DiskSpaceInfo[]>();
の代わりにConsole.Write(test2);
を使用できるというだけで、"@ Giu Do"ソリューションを使用できます。
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を使用しました。これは、受け取ったjsonの最初のノードであるdの後の最初のノードを見つける必要があるためです。
Mainを再現する関数を作成する必要があります。回避するために、オブジェクトがnullでないかどうかを確認することを忘れないでくださいNullReferenceException。