2011-09-20 16 views
15

Leo desde el DB hace mucho tiempo. Quiero solo un atributo de ese json.¿Puedo deserializar json al tipo anónimo en C#?

Tengo dos opciones: a. Crea una interfaz para ese json y deserializa a esa interfaz. (¿Es una exageración ya que solo necesito un atributo?) b. Encontrar la subcadena que necesito (¿regex?)

¿cuál se prefiere?

actualización: estoy usando .NET 3.5

Respuesta

26

¿Por qué no usar Deserialize JSON.NET 's enfoque de "LINQ a JSON" (JObject etc) y sólo pregunta por el valor que necesita por su nombre?

Eso es lo suficientemente dinámico para que no necesite crear una interfaz para todo, pero es mucho menos frágil que usar una expresión regular.

JObject json = JObject.Parse(text); 
JToken value = json["foo"]["bar"]; 

(creo JSON.NET también, pero no de dynamic en .NET 4 de soporte sin necesidad particular para usar aquí.)

2

En .NET 4:

se puede hacer algo tipo de lo que quiere menos la necesidad de expresiones regulares (y no debe usar expresiones regulares para algo como esto) utilizando la característica dynamic de C# 4.0 que se describe aquí: http://www.drowningintechnicaldebt.com/ShawnWeisfeld/archive/2010/08/22/using-c-4.0-and-dynamic-to-parse-json.aspx

El único inconveniente es que no puede garantizar lo que el e La estructura xact del objeto es

El repunte es que en lugar de acceder a través de los miembros yourDynamicObject['blah'], que es el más pato-tipo-ish yourDynamicObject.blah

En .NET 3.5:

Puede utilizar Json.NET: http://json.codeplex.com/

18

Regex debe estar absolutamente fuera de toda discusión. Solo olvídalo, es como si nunca hubiera existido.

Crear y trabajar con tipos fuertes es algo bueno y, probablemente, la forma en que iría.

Pero si se quiere, se puede también utilizar dynamic:

class Program 
{ 
    static void Main() 
    { 
     var json = "{ 'foo': { 'bar': 'bar value', 'baz': [ 1, 2, 3 ] } }"; 
     var serializer = new JavaScriptSerializer(); 
     dynamic value = serializer.DeserializeObject(json); 
     Console.WriteLine(value["foo"]["baz"][1]); 
    } 
} 

impresiones 2 en la consola.

+0

Estoy usando C# 3.5 No creo que haya un tipo dinámico. derecho ? –

+2

@Elad Benda, no, no hay. Bueno, entonces podrías usar [Json.NET] (http://json.codeplex.com/) que ofrece una sintaxis similar. –

0

Depende.

La opción A es la forma más estricta, disciplinada y formal. Sin embargo, una vez más, como dijiste, puede ser excesivo. ¿Qué tan gordo es ese json? A largo plazo, la opción A deja la posibilidad potencial futura de que necesite usar más de una propiedad.

La opción B es definitivamente más informal y directa. Definitivamente funcionará hoy, pero puede requerir una solución diferente en el futuro.

Por lo tanto, tal vez desee envolver todo el proceso en un método para ocultar la implementación del cliente que realiza la llamada. Devuelve tu objeto personalizado con solo la propiedad solitaria poblada. Luego, si surge la necesidad en el futuro, puede cambiar el método para utilizar la deserialización de inclinación total.

Nota: No creo que la deserialización a un tipo anónimo en C# 3.5 sea posible.

1

Encontrar la subcadena es una optimización peligrosa.

¿Vale la pena optimizar el proceso (en comparación con una deserialización JSON) y hacer esta búsqueda de forma segura? No podemos responder porque depende principalmente del contexto. Pero me gustaría decir NO porque obviamente está buscando problemas: incluso si funciona ahora, puede romperse en el futuro cuando cambie la estructura o el contenido de su objeto.

1

Hilo viejo, pero aquí va otro método en .NET 3.5: puede convertir el objeto devuelto por DeserializeObject a un < del Diccionario String, Object >. Es una especie de la misma solución que usar la palabra clave dinámica .NET 4.0:

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
Object obj = serializer.DeserializeObject("{ 'name': 'vinicius fonseca', 'age': 31 }"); 
Dictionary<String, Object> ret = (Dictionary<String, Object>)obj; 
Console.WriteLine(ret["name"].GetType().Name); // Output: String 
Console.WriteLine(ret["name"].ToString()); // Output: vinicius fonseca 
Console.WriteLine(ret["age"].GetType().Name); // Output: Int32 
Console.WriteLine(ret["age"].ToString()); // Output: 31 

Espero que ayude a alguien.

Saludos

0

que puede hacer:

var result = JsonConvert.DeserializeAnonymousType(json, new { Foo="", Bar=""}); 

Esto devolverá un objeto dinámico con los campos que ha definido.

+0

¿Podría elaborar más su respuesta agregando un poco más de descripción acerca de la solución que proporciona? – abarisone

Cuestiones relacionadas