É possível retornar um objeto dinâmico de uma desserialização json usando json.net? Eu gostaria de fazer algo assim:
dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
É possível retornar um objeto dinâmico de uma desserialização json usando json.net? Eu gostaria de fazer algo assim:
dynamic jsonResponse = JsonConvert.Deserialize(json);
Console.WriteLine(jsonResponse.message);
Respostas:
O Json.NET nos permite fazer isso:
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);
Resultado:
1000
string
6
Documentação aqui: LINQ to JSON com Json.NET
Consulte também JObject.Parse e JArray.Parse
JArray.Parse
.
Dim d As Object = JObject.Parse("{number:1000, str:'string', array: [1,2,3,4,5,6]}")
A partir do Json.NET 4.0 Release 1, há suporte dinâmico nativo:
[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>());
}
E, é claro, a melhor maneira de obter a versão atual é via NuGet.
Atualizado (11/12/2014) para tratar dos comentários:
Isso funciona perfeitamente bem. Se você inspecionar o tipo no depurador, verá que o valor é de fato dinâmico . O tipo subjacente é a JObject
. Se você deseja controlar o tipo (como especificar ExpandoObject
, faça-o).
@Model.Prop
nome no Razor se o tipo de retorno for JValue.
JValue
. O que me confundiu porque eu estava trabalhando na janela do depurador / janela imediata e não estava vendo apenas string
s. David mostra isso na captura de tela inferior. A JValue
é conversível para que você pode apenas fazerstring m = jsonResponse.message
Se você apenas desserializar para dinâmico, receberá um JObject de volta. Você pode obter o que deseja usando um ExpandoObject.
var converter = new ExpandoObjectConverter();
dynamic message = JsonConvert.DeserializeObject<ExpandoObject>(jsonString, converter);
Eu sei que esse post é antigo, mas o JsonConvert realmente tem um método diferente, então seria
var product = new { Name = "", Price = 0 };
var jsonResponse = JsonConvert.DeserializeAnonymousType(json, product);
Sim, você pode fazer isso usando o JsonConvert.DeserializeObject. Para fazer isso, basta fazer:
dynamic jsonResponse = JsonConvert.DeserializeObject(json);
Console.WriteLine(jsonResponse["message"]);
JsonConvert
não contém um método chamado Deserialize
.
Nota: No momento em que respondi a essa pergunta em 2010, não havia como desserializar sem algum tipo, isso permitiu que você desserializasse sem precisar definir a classe real e permitir que uma classe anônima fosse usada para fazer a desserialização.
Você precisa ter algum tipo de tipo para desserializar. Você poderia fazer algo como:
var product = new { Name = "", Price = 0 };
dynamic jsonResponse = JsonConvert.Deserialize(json, product.GetType());
Minha resposta é baseada em uma solução para compilação do .NET 4.0 no serializador JSON. O link para desserializar para tipos anônimos está aqui:
Se você usa o JSON.NET com a versão antiga que não JObject.
Esta é outra maneira simples de criar um objeto dinâmico a partir do JSON: https://github.com/chsword/jdynamic
Instalação do NuGet
PM> Install-Package JDynamic
Suporte usando o índice de string para acessar membros como:
dynamic json = new JDynamic("{a:{a:1}}");
Assert.AreEqual(1, json["a"]["a"]);
Caso de teste
E você pode usar este utilitário da seguinte maneira:
Obtenha o valor diretamente
dynamic json = new JDynamic("1");
//json.Value
2.Obtenha o membro no objeto 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.
De outros
dynamic json = new JDynamic("{a:{a:1} }");
//json.a.a is 1.
Sim, é possível. Eu tenho feito isso o tempo todo.
dynamic Obj = JsonConvert.DeserializeObject(<your json string>);
É um pouco mais complicado para o tipo não nativo. Suponha que dentro do seu Obj, haja objetos ClassA e ClassB. Todos eles são convertidos em JObject. O que você precisa fazer é:
ClassA ObjA = Obj.ObjA.ToObject<ClassA>();
ClassB ObjB = Obj.ObjB.ToObject<ClassB>();