Json.net을 사용하여 json 객체를 동적 객체로 직렬화 해제


426

json.net을 사용하여 json deserialization에서 동적 객체를 반환 할 수 있습니까? 나는 이런 식으로하고 싶다 :

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

1
JSON json2csharp.com 에서 C # 클래스를 생성 하고 동적 대신 생성 된 클래스를 사용하는 것을 고려하십시오
Michael Freidgeim


stackOverflow가 "너무 오래된"질문을 어떻게 닫을 것을 제안합니까? 6 년이 지났으며 그 이후로 모든 버전의 .net에 대한 올바른 답변과 합리적인 제안이 있습니다. 너무 많아서 더 이상 도움이되지 않습니다.
Andrew Lorien이

답변:


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.ParseJArray.Parse를 참조하십시오.


36
배열의 경우 구문은 JArray.Parse입니다.
jgillich

4
왜 동적 단어를 사용해야합니까? 난 겁 전에 사용한 적이 있어요 : D
MonsterMMORPG

3
VB.Net에서해야 할 일Dim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
ilans

2
@MonsterMMORPG 당신은 :) 동적은 거의 모든 상황에서 안티 패턴이지만, 때때로, 그리고 당신은 그것을 사용하는 것이 합리적 일 수 있습니다.
Pluc

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 : at 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 일) :

이것은 완벽하게 작동합니다. 디버거에서 유형을 검사하면 값이 실제로 dynamic인지 알 수 있습니다. 기본 유형 A는 JObject. 유형을 제어하려면 (예 : 지정 ExpandoObject) 그렇게하십시오.

여기에 이미지 설명을 입력하십시오


20
이것은 결코 작동하지 않는 것 같습니다. 동적 변수가 아닌 JObject 만 반환합니다.
Paul

12
BTW, 작동 : JsonConvert.DeserializeObject <ExpandoObject> (STRING); 적절한 역 직렬화로 JObject 등이 없습니다.
Gutek

2
@Gutek 문제가 무엇인지 잘 모르겠습니다. 코드를 실행 했습니까? 테스트에 어설 션을 추가하고 원래 json에없는 속성을 추가했습니다. 디버거의 스크린 샷이 포함되었습니다.
David Peden

1
@DavidPeden JObject가 있고 Razor에서 바인딩하려고하면 예외가 발생합니다. JObject는 동적이지만 기본 유형이 아닌 JValue와 같은 "자체"유형을 포함합니다. @Model.Prop반환 유형이 JValue 인 경우 Razor에서 이름을 사용할 수 없습니다 .
Gutek

2
이것은 작동하지만 각 동적 속성은입니다 JValue. 디버거 / 즉시 창에서 작업하고 strings 만 보지 않아서 혼란 스럽습니다 . David는 이것을 아래 스크린 샷에 표시합니다. 은 JValue그냥 할 수 있도록 개조 할 수있다string m = jsonResponse.message
누가 복음 Puplett

66

동적으로 역 직렬화하면 JObject가 다시 나타납니다. ExpandoObject를 사용하여 원하는 것을 얻을 수 있습니다.

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

1
결과는 사전으로 변환 될 수 있습니다
FindOutIslamNow

1
정확히 내가 찾은 것! 감사!
DarkDeny 2009 년

42

나는 이것이 오래된 게시물이라는 것을 알고 있지만 JsonConvert는 실제로 다른 방법을 가지고 있으므로

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

23
그것은 json 페이로드를 동적 유형이 아닌 익명 유형으로 역 직렬화하는 것입니다. 익명 유형과 동적 유형은 서로 다르므로 질문이 해결되지 않았다고 생각합니다.
jrista

1
두 개의 변수를 사용해야합니까? 두 번째 진술에서 첫 번째 것을 재사용하지 않겠습니까?
RenniePet

21

예, JsonConvert.DeserializeObject를 사용하여 수행 할 수 있습니다. 그렇게하려면 간단하게 수행하십시오.

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

1
JsonConvert라는 메소드를 포함하지 않습니다 Deserialize.
Can Poyrazoğlu가

DeserializeObject 여야하지만 이것은 허용 된 답변이어야합니다. IMO
superjugy

21

참고 : 2010 년 에이 질문에 대답했을 때 어떤 종류의 유형없이 직렬화를 해제 할 수있는 방법이 없었으므로 실제 클래스를 정의하지 않고도 직렬화를 해제하고 익명화 클래스를 사용하여 직렬화 해제를 수행 할 수있었습니다.


역 직렬화하려면 일종의 유형이 필요합니다. 다음 라인을 따라 무언가를 할 수 있습니다.

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

내 대답은 JSON serializer의 .NET 4.0 빌드 솔루션을 기반으로합니다. 익명 유형으로 직렬화 해제 링크는 다음과 같습니다.

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


나는 당신과 함께 phill 모르겠어요 왜 사람들이 이것을 거절 투표, 당신이 할 수있는 경우 .. 왜 설명하십시오?
PEO

18
유형이없는 직렬화 해제에 대한 질문이기 때문에 하향 조정됩니다.
Richard Richard

4
다른 솔루션이 없었던 2010 년에 답변을 작성했을 때 답변이 유효했습니다. JSON.NET에서 지원이 제공 될 때까지 짧은 시간 동안 받아 들여진 대답이었습니다.
Phill

1
이것은 동적 객체를 생성하지 않습니다. 그러면 동적으로 참조하는 JObject가 생성됩니다. 그러나 여전히 JObject가 있습니다.
ghostbust555

5

JObject가 아닌 이전 버전으로 JSON.NET을 사용하는 경우.

이것은 JSON에서 동적 객체를 만드는 또 다른 간단한 방법입니다. 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.