Json.netを使用してjsonオブジェクトを動的オブジェクトに逆シリアル化する


426

json.netを使用してjsonの逆シリアル化から動的オブジェクトを返すことは可能ですか?私はこのようなことをしたいと思います:

dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);

1
JSON json2csharp.comからC#クラスを生成し、動的ではなく生成されたクラスを使用することを検討してください
Michael Freidgeim


stackOverflowが「古すぎる」と質問を閉じることをどのように提案しますか?それは6年になります。それ以来、.netのすべてのバージョンに有効な回答と合理的な提案があります...非常に多く、あまり役に立たなくなっています。
アンドリューlorien 2017

回答:


546

Json.NETはこれを可能にします:

dynamic d = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}");

Console.WriteLine(d.number);
Console.WriteLine(d.str);
Console.WriteLine(d.array.Count);

出力:

 1000
 string
 6

ここのドキュメント:Json.NETを使用したLINQ to JSON

JObject.ParseおよびJArray.Parseも参照してください


36
配列の構文はであることに注意してくださいJArray.Parse
jgillich 2014年

4
動的な単語を使用する必要があるのはなぜですか?私は今まで使ったことがないのが怖い:D
MonsterMMORPG 2014

3
VB.Netで行う必要がありますDim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
ilans 2014

2
@MonsterMMORPGする必要があります:)ダイナミックはほとんどすべての状況でアンチパターンですが、時々、それを使用することが合理的である状況があるかもしれません。
Pluc 2016年

4
Newtonsoft.Json 8.0.3(.NET 4.5.2)の場合:Microsoft.CSharp.RuntimeBinder.RuntimeBinderExceptionが発生しましたHResult = -2146233088 Message = 'Newtonsoft.Json.Linq.JObject'には 'number'の定義が含まれていませんSource = Microsoft .CSharp StackTrace:Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError(CError pError)
user4698855

107

Json.NET 4.0リリース1以降、ネイティブの動的サポートがあります。

[Test]
public void DynamicDeserialization()
{
    dynamic jsonResponse = JsonConvert.DeserializeObject("{\"message\":\"Hi\"}");
    jsonResponse.Works = true;
    Console.WriteLine(jsonResponse.message); // Hi
    Console.WriteLine(jsonResponse.Works); // True
    Console.WriteLine(JsonConvert.SerializeObject(jsonResponse)); // {"message":"Hi","Works":true}
    Assert.That(jsonResponse, Is.InstanceOf<dynamic>());
    Assert.That(jsonResponse, Is.TypeOf<JObject>());
}

そしてもちろん、現在のバージョンを取得する最良の方法はNuGetを使用することです。

コメントに対処するために更新(2014年11月12日):

これは完璧に機能します。デバッガーで型を調べると、値が実際には動的であることがわかります。根本的なタイプがありますJObject。タイプを制御したい場合(の指定ExpandoObjectなど)、そうします。

ここに画像の説明を入力してください


20
これはうまくいかないようです。動的変数ではなく、JObjectのみを返します。
Paul

12
ところで、これは動作します:JsonConvert.DeserializeObject <ExpandoObject>(STRING); 適切な逆シリアル化により、JObjectなどがありません
Gutek

2
@Gutekはあなたの問題が何であるかわからない。コードを実行しましたか?テストにアサートを追加し、元のjsonにはないプロパティを追加しました。含まれているデバッガのスクリーンショット。
David Peden 2014年

1
@DavidPeden JObjectがあり、それをRazorでバインドしようとすると、例外が発生します。質問は、動的オブジェクトへの逆シリアル化についてでした-JObjectは動的ですが、プリミティブ型ではなくJValueのような「独自の」型が含まれています。@Model.Prop戻り値の型がJValueの場合、Razorで名前を使用できません。
Gutek、2014年

2
これは機能しますが、各動的プロパティはJValueです。デバッガー/イミディエイトウィンドウで作業していて、strings だけが表示されていなかったため、どちらが混乱したか。Davidはこれを下のスクリーンショットで示しています。これJValueは変換できるので、あなたはただ行うことができますstring m = jsonResponse.message
ルーク・プレット

66

動的にデシリアライズするだけで、JObjectが返されます。ExpandoObjectを使用すると、必要なものを取得できます。

var converter = new ExpandoObjectConverter();    
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);

1
結果は辞書に変換することもできます
FindOutIslamNow

1
まさに私が探していたもの!ありがとう!
DarkDeny

42

私はこれが古い投稿であることを知っていますが、JsonConvertは実際には別のメソッドを持っているので、

var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);

23
それは、jsonペイロードを動的な型ではなく匿名の型に逆シリアル化することになります。匿名型と動的型は異なるものであり、これが尋ねられた質問に対処するとは思わない。
jrista 2012

1
2つの変数を使用する必要がありますか?2番目のステートメントで最初のステートメントを再利用しませんか?
RenniePet 2013

21

はい、JsonConvert.DeserializeObjectを使用して実行できます。それを行うには、単純に次のようにします。

dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);

1
JsonConvertというメソッドが含まれていませんDeserialize
CanPoyrazoğlu2015年

それは単にDeserializeObjectである必要がありますが、これは受け入れられた回答であるはずですIMO
superjugy

21

注: 2010年にこの質問に回答した時点では、なんらかのタイプなしでデシリアライズする方法はありませんでした。これにより、実際のクラスを定義せずにデシリアライズでき、匿名クラスを使用してデシリアライズを実行できました。


逆シリアル化する型の種類が必要です。あなたは次の線に沿って何かをすることができます:

var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());

私の答えは、JSONシリアライザーでの.NET 4.0のビルドのソリューションに基づいています。匿名型への逆シリアル化へのリンクはここにあります:

http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx


私はあなたと一緒にいます。なぜ誰かがこれを反対票を投じるのかわかりません。
PEO

18
問題は型なしで逆シリアル化することに関するものであるため、反対票を投じています。
リチャード

4
回答は、他に解決策がなかった2010年の執筆時点で有効でした。JSON.NETでサポートが提供されるまで、それは少しの間でも受け入れられた回答でした。
フィル

1
これは動的オブジェクトを生成しません。これにより、動的として参照するJObjectが生成されます。しかし、それでも内部にはJObjectがあります。
ghostbust555

5

JObjectを含まない古いバージョンでJSON.NETを使用する場合。

これは、JSONから動的オブジェクトを作成するもう1つの簡単な方法です。https//github.com/chsword/jdynamic

NuGetインストール

PM> Install-Package JDynamic

次のようなメンバーにアクセスするための文字列インデックスの使用をサポートします。

dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);

テストケース

そして、あなたはこのユーティリティを次のように使うことができます:

直接値を取得

dynamic json = new JDynamic("1");

//json.Value

2. jsonオブジェクトのメンバーを取得する

dynamic json = new JDynamic("{a:'abc'}");
//json.a is a string "abc"

dynamic json = new JDynamic("{a:3.1416}");
//json.a is 3.1416m

dynamic json = new JDynamic("{a:1}");
//json.a is integer: 1

3.IEnumerable

dynamic json = new JDynamic("[1,2,3]");
/json.Length/json.Count is 3
//And you can use json[0]/ json[2] to get the elements

dynamic json = new JDynamic("{a:[1,2,3]}");
//json.a.Length /json.a.Count is 3.
//And you can use  json.a[0]/ json.a[2] to get the elements

dynamic json = new JDynamic("[{b:1},{c:1}]");
//json.Length/json.Count is 2.
//And you can use the  json[0].b/json[1].c to get the num.

その他の

dynamic json = new JDynamic("{a:{a:1} }");

//json.a.a is 1.

2

はい、可能です。私はずっとそうしてきました。

dynamic Obj = JsonConvert.DeserializeObject(<your json string>);

非ネイティブ型には少し注意が必要です。Objの内部にClassAオブジェクトとClassBオブジェクトがあるとします。それらはすべてJObjectに変換されます。あなたがする必要があるのは:

ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.