Как вы предлагаете stackOverflow закрыть вопрос как "слишком старый"? Прошло шесть лет, с тех пор есть правильные ответы и разумные предложения для каждой версии .net ... так много, что они больше не помогают.
Эндрю Лориен
Ответы:
547
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);
Обратите внимание, что для массивов синтаксис 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 Вы должны быть :) Dynamic - это анти-паттерн почти во всех обстоятельствах, но время от времени у вас может возникнуть ситуация, когда его целесообразно использовать.
Pluc
4
В случае Newtonsoft.Json 8.0.3 (.NET 4.5.2): возникло исключение Microsoft.CSharp.RuntimeBinder.RuntimeBinderException HResult = -2146233088 Сообщение = 'Newtonsoft.Json.Linq.JObject' не содержит определения для 'number' Source = Microsoft .CSharp StackTrace: в Microsoft.CSharp.RuntimeBinder.RuntimeBinderController.SubmitError (CError pError)
user4698855
107
Начиная с Json.NET 4.0 Release 1 имеется встроенная динамическая поддержка:
И, конечно же, лучший способ получить текущую версию - через NuGet.
Обновлено (12/12/2014) для учета комментариев:
Это прекрасно работает. Если вы проверите тип в отладчике, вы увидите, что значение, по сути, является динамическим . Базового типа является JObject. Если вы хотите контролировать тип (например, указать ExpandoObject, то сделайте это).
Кажется, это никогда не работает. Он возвращает только JObject, а не динамическую переменную.
Пол
12
Кстати, это работает: JsonConvert.DeserializeObject <ExpandoObject> (STRING); с правильной десериализацией, поэтому у нас нет JObject и т. д.
Gutek
2
@ Гутек не уверен, в чем твоя проблема. Вы запускали код? Я добавил утверждения в тест и добавил свойство, отсутствующее в исходном json. Скриншот отладчика включен.
Дэвид Педен
1
@DavidPeden, если у вас есть JObject и вы попытаетесь связать это, в Razor вы получите исключения. Вопрос был о десериализации динамического объекта - JObject является динамическим, но содержит «собственные» типы, такие как JValue, а не примитивные типы. Я не могу использовать @Model.Propимя в Razor, если тип возвращаемого значения - JValue.
Гутек
2
Это работает, но каждое динамическое свойство является JValue. Что смутило меня, потому что я работал в окне отладчика / непосредственного окна и не видел только strings. Дэвид показывает это на нижнем скриншоте. Это JValueконвертируемый, так что вы можете просто сделатьstring m = jsonResponse.message
Люк Пуплетт
66
Если вы просто десериализуетесь в динамический, вы получите JObject обратно. Вы можете получить то, что вы хотите, используя ExpandoObject.
var converter =newExpandoObjectConverter();dynamic message =JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
Это было бы десериализацией полезной нагрузки json в анонимный тип, а не динамический тип. Анонимные типы и динамические типы - это разные вещи, и я не верю, что это отвечает на заданный вопрос.
jrista
1
Нужно ли использовать две переменные? Почему бы не использовать первый во втором утверждении?
RenniePet
21
Да, вы можете сделать это с помощью JsonConvert.DeserializeObject. Для этого достаточно просто сделать:
JsonConvertне содержит вызванный метод Deserialize.
Может Пойразоглу
это должен быть только DeserializeObject, но это должен быть принятый ответ IMO
superjugy
21
Примечание. В то время, когда я отвечал на этот вопрос в 2010 году, не было никакого способа десериализации без какого-либо типа, это позволило вам десериализовать, не определяя фактический класс, и разрешило использовать анонимный класс для десериализации.
Вы должны иметь какой-то тип для десериализации. Вы могли бы сделать что-то вроде:
var product =new{Name="",Price=0};dynamic jsonResponse =JsonConvert.Deserialize(json, product.GetType());
Мой ответ основан на решении для сборки .NET 4.0 в сериализаторе JSON. Ссылка для десериализации на анонимные типы находится здесь:
Я с тобой, Фил, не знаю, почему люди голосуют против этого, если кто-нибудь может, пожалуйста, объясните, почему?
PEO
18
Они понижают голос, потому что речь идет о десериализации без типа.
Ричард
4
Ответ был действителен на момент написания его в 2010 году, когда не было другого решения. Это был даже принятый ответ в течение небольшого периода времени, пока не появилась поддержка в JSON.NET.
Фил
1
Это не производит динамический объект. Это создает JObject, который вы называете динамическим. Но это все еще JObject внутри.
ghostbust555
5
Если вы используете JSON.NET со старой версией, которая не JObject.
И вы можете использовать эту утилиту следующим образом:
Получить значение напрямую
dynamic json =newJDynamic("1");//json.Value
2. Получить член в объекте json
dynamic json =newJDynamic("{a:'abc'}");//json.a is a string "abc"dynamic json =newJDynamic("{a:3.1416}");//json.a is 3.1416mdynamic json =newJDynamic("{a:1}");//json.a is integer: 1
3.IEnumerable
dynamic json =newJDynamic("[1,2,3]");/json.Length/json.Countis3//And you can use json[0]/ json[2] to get the elementsdynamic json =newJDynamic("{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 elementsdynamic json =newJDynamic("[{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 =newJDynamic("{a:{a:1} }");//json.a.a is 1.
Это немного сложнее для неродного типа. Предположим, внутри вашего объекта Obj есть объекты ClassA и ClassB. Все они конвертированы в JObject. Что вам нужно сделать, это:
Ответы:
Json.NET позволяет нам сделать это:
Вывод:
Документация здесь: LINQ to JSON с Json.NET
Смотрите также JObject.Parse и JArray.Parse
источник
JArray.Parse
.Dim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
Начиная с Json.NET 4.0 Release 1 имеется встроенная динамическая поддержка:
И, конечно же, лучший способ получить текущую версию - через NuGet.
Обновлено (12/12/2014) для учета комментариев:
Это прекрасно работает. Если вы проверите тип в отладчике, вы увидите, что значение, по сути, является динамическим . Базового типа является
JObject
. Если вы хотите контролировать тип (например, указатьExpandoObject
, то сделайте это).источник
@Model.Prop
имя в Razor, если тип возвращаемого значения - JValue.JValue
. Что смутило меня, потому что я работал в окне отладчика / непосредственного окна и не видел толькоstring
s. Дэвид показывает это на нижнем скриншоте. ЭтоJValue
конвертируемый, так что вы можете просто сделатьstring m = jsonResponse.message
Если вы просто десериализуетесь в динамический, вы получите JObject обратно. Вы можете получить то, что вы хотите, используя ExpandoObject.
источник
Я знаю, что это старый пост, но JsonConvert на самом деле имеет другой метод, поэтому было бы
источник
Да, вы можете сделать это с помощью JsonConvert.DeserializeObject. Для этого достаточно просто сделать:
источник
JsonConvert
не содержит вызванный методDeserialize
.Примечание. В то время, когда я отвечал на этот вопрос в 2010 году, не было никакого способа десериализации без какого-либо типа, это позволило вам десериализовать, не определяя фактический класс, и разрешило использовать анонимный класс для десериализации.
Вы должны иметь какой-то тип для десериализации. Вы могли бы сделать что-то вроде:
Мой ответ основан на решении для сборки .NET 4.0 в сериализаторе JSON. Ссылка для десериализации на анонимные типы находится здесь:
http://blogs.msdn.com/b/alexghi/archive/2008/12/22/using-anonymous-types-to-deserialize-json-data.aspx
источник
Если вы используете JSON.NET со старой версией, которая не JObject.
Это еще один простой способ сделать динамический объект из JSON: https://github.com/chsword/jdynamic
NuGet Установить
Поддержка использования строкового индекса для доступа к члену, как:
Прецедент
И вы можете использовать эту утилиту следующим образом:
Получить значение напрямую
2. Получить член в объекте json
3.IEnumerable
Другой
источник
Да, это возможно. Я делал это все время.
Это немного сложнее для неродного типа. Предположим, внутри вашего объекта Obj есть объекты ClassA и ClassB. Все они конвертированы в JObject. Что вам нужно сделать, это:
источник