2011-01-06 34 views
118

Intentando convertir una cadena JSON en un objeto en C#. Usando un caso de prueba realmente simple:Convertir cadena JSON en C# Objeto

JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }"); 

El problema es que routes_list nunca se establece; es un objeto indefinido ¿Algunas ideas?

+1

@ Greg: En realidad recomienda el JavaScriptSerializer' más de MS versión 'ya que no se acepte cualquier otra cosa que el formato JSON personalizado de WCF (por ejemplo, los campos de fecha que parecen fechas pero no están rodeados en DATE() fallan miserablemente) –

+0

Además, mire esto [Análisis de objetos JSON con JavascriptSerializer en .NET] (http: // www) .tomasvera.com/programación/using-javascriptserializer-to-parse-json-objects /) artículo, que en realidad es un gran tutorial. – scatmoi

+0

¿Dónde obtiene JavaScriptSerializer? No se reconoce en mi proyecto C# .NET 3.5. –

Respuesta

92

Parece que usted está tratando de deserializar un objeto de crudo. Puede crear una clase que represente el objeto al que está convirtiendo. Esto sería más útil en los casos en los que se trata de objetos más grandes o Cadenas JSON.

Por ejemplo:

class Test { 

     String test; 

     String getTest() { return test; } 
     void setTest(String test) { this.test = test; } 

    } 

A continuación, el código de deserialización sería:

JavaScriptSerializer json_serializer = new JavaScriptSerializer(); 
    Test routes_list = 
      (Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }"); 

Más información se puede encontrar en este tutorial: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

+1

Pero en el artículo puntual se usan autopropiedades. Vale la pena mencionar también. –

+7

Lo sentimos, pero este ejemplo de código no funciona. DeserializeObject da una excepción. Use var routes_list = serializer.Deserialize ("{\" test \ ": \" some data \ "}"); en lugar. Además, no es necesario que get/setTest() y String test sean públicos. Esto se parece más a Java que a C#. – dvallejo

+0

como mencionó Dan Vallejo, esta es una solución incorrecta. Después de todo, setTest (String test) no regresa, que también es un error de compilación. – user843681

48

Probablemente no desee simplemente declarar routes_list como un tipo object. No tiene una propiedad .test, por lo que realmente no va a recuperar un buen objeto. Este es uno de esos lugares donde sería mejor definir una clase o una estructura, o hacer uso de la palabra clave dinámica.

Si realmente desea que este código funcione como lo tiene, necesitará saber que el objeto devuelto por DeserializeObject es un diccionario genérico de cadena, objeto. Aquí está el código para hacerlo de esa manera:

var json_serializer = new JavaScriptSerializer(); 
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }"); 
Console.WriteLine(routes_list["test"]); 

Si desea utilizar la palabra clave dinámica, you can read how here.

Si se declara una clase o estructura, puede llamar Deserialize en lugar de DeserializeObject así:

class MyProgram { 
    struct MyObj { 
     public string test { get; set; } 
    } 

    static void Main(string[] args) { 
     var json_serializer = new JavaScriptSerializer(); 
     MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }"); 
     Console.WriteLine(routes_list.test); 

     Console.WriteLine("Done..."); 
     Console.ReadKey(true); 
    } 
} 
+0

Hacer: json_serializer = new JavaScriptSerializer(); objeto routes_list = (IDictionary ) json_serializer.DeserializeObject ("{\" test \ ": \" algunos datos aquí \ "}"); Aún no aparece 'routes_list' en el contexto actual. – Justin

+0

No use 'object routes_list'. Use 'var' o repítase explícitamente y declare routes_list como IDictionary . – mattmc3

+0

Esto funcionó para mí, ¡Gracias! ¡La solución seleccionada NO! –

11

Aquí es una clase simple que armó desde varios mensajes .... Se ha probado durante aproximadamente 15 minutos, pero parece para trabajo para mis propósitos Utiliza JavascriptSerializer para hacer el trabajo, al que se puede hacer referencia en tu aplicación usando la información detallada in this post.

El código siguiente se puede ejecutar en LINQPad para probarlo por:

  • Al hacer clic derecho en la pestaña de script en LINQPad, y seleccionando "Propiedades" de consulta
  • referencia a la "System.Web. Extensions.dll "en" Referencias adicionales "
  • Agregar una" Importación de espacio de nombre adicional "de " System.Web.Script.Serialization ".

Espero que ayude!

void Main() 
{ 
    string json = @" 
    { 
    'glossary': 
    { 
     'title': 'example glossary', 
     'GlossDiv': 
     { 
      'title': 'S', 
      'GlossList': 
      { 
      'GlossEntry': 
      { 
       'ID': 'SGML', 
       'ItemNumber': 2,   
       'SortAs': 'SGML', 
       'GlossTerm': 'Standard Generalized Markup Language', 
       'Acronym': 'SGML', 
       'Abbrev': 'ISO 8879:1986', 
       'GlossDef': 
       { 
       'para': 'A meta-markup language, used to create markup languages such as DocBook.', 
       'GlossSeeAlso': ['GML', 'XML'] 
       }, 
       'GlossSee': 'markup' 
      } 
      } 
     } 
    } 
    } 

    "; 

    var d = new JsonDeserializer(json); 
    d.GetString("glossary.title").Dump(); 
    d.GetString("glossary.GlossDiv.title").Dump(); 
    d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump(); 
    d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();  
    d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump(); 
    d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump(); 
    d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump(); 
} 


// Define other methods and classes here 

public class JsonDeserializer 
{ 
    private IDictionary<string, object> jsonData { get; set; } 

    public JsonDeserializer(string json) 
    { 
    var json_serializer = new JavaScriptSerializer(); 

    jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json); 
    } 

    public string GetString(string path) 
    { 
    return (string) GetObject(path); 
    } 

    public int? GetInt(string path) 
    { 
    int? result = null; 

    object o = GetObject(path); 
    if (o == null) 
    { 
     return result; 
    } 

    if (o is string) 
    { 
     result = Int32.Parse((string)o); 
    } 
    else 
    { 
     result = (Int32) o; 
    } 

    return result; 
    } 

    public object GetObject(string path) 
    { 
    object result = null; 

    var curr = jsonData; 
    var paths = path.Split('.'); 
    var pathCount = paths.Count(); 

    try 
    { 
     for (int i = 0; i < pathCount; i++) 
     { 
     var key = paths[i]; 
     if (i == (pathCount - 1)) 
     { 
      result = curr[key]; 
     } 
     else 
     { 
      curr = (IDictionary<string, object>)curr[key]; 
     } 
     } 
    } 
    catch 
    { 
     // Probably means an invalid path (ie object doesn't exist) 
    } 

    return result; 
    } 
} 
5

añadir esta DDL para hacer referencia a su proyecto: System.Web.Extensions.dll

uso este espacio de nombres: usando System.Web.Script.Publicación por entregas;

public class IdName 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
} 


    string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\""); 
    var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle); 

    string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\""); 
    var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection); 
98

O bien, puede utilizar la biblioteca Newtownsoft.Json de la siguiente manera:

using Newtonsoft.Json; 
... 
var result = JsonConvert.DeserializeObject<T>(json); 

Dónde T es su tipo de objeto que coincide con su cadena JSON.

+0

Es tan fácil y pensé mucho sobre cómo hacer esto. –

25

Uso de objetos dinámicos con JavaScriptSerializer.

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }"); 
string test= item["test"]; 

//test Result = "some data" 
16

Newtonsoft es más rápido que el serializador de script java. ... este depende del paquete Newtonsoft NuGet, que es popular y mejor que el serializador predeterminado.

solución de código de una línea.

var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring); 

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring); 
9

Puede realizar su requerimiento fácilmente utilizando la biblioteca Newtonsoft.Json. Estoy anotando el siguiente ejemplo, eche un vistazo.

clase para el tipo de objeto que recibe:

public class User 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 

} 

Código:

static void Main(string[] args) 
{ 

     string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}"; 

     User user = JsonConvert.DeserializeObject<User>(json); 

     Console.ReadKey(); 
} 

esta es una manera muy simple para analizar su JSON.

0

Convierte una cadena JSON en un objeto en C#. Usar el caso de prueba debajo ... funcionó para mí. Aquí "MenuInfo" es mi objeto de la clase C#.

JsonTextReader reader = null; 
try 
{ 
    WebClient webClient = new WebClient(); 
    JObject result = JObject.Parse(webClient.DownloadString("YOUR URL")); 
    reader = new JsonTextReader(new System.IO.StringReader(result.ToString())); 
    reader.SupportMultipleContent = true; 
} 
catch(Exception) 
{} 

JsonSerializer serializer = new JsonSerializer(); 
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader); 
2

Otra forma rápida y fácil de semi-automatizar estos pasos es:

  1. tomar el JSON que desea analizar y pegarlo aquí: http://json2csharp.com/ a continuación, copiar y pegar el resultado en una nueva clase (ej: MyClass) en Visual Studio.
  2. Cambie el nombre de "RootObject" en la salida de json2csharp a "MyClass" o como lo llame.
  3. En el estudio visual, vaya al sitio web -> Administrar paquetes y utilice NuGet para agregar Json.Net desde Newtonsoft.

Ahora use código como:

WebClient client = new WebClient(); 

string myJSON = client.DownloadString("https://URL_FOR_JSON.com/JSON_STUFF"); 

var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject(myJSON); 
0

primer lugar hay que incluir biblioteca como:

using System.Runtime.Serialization.Json; 

DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite)); 
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}"; 

using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json))) 
{ 
    BlogSite b = (BlogSite)desc.ReadObject(ms); 
    Console.WriteLine(b.Name); 
    Console.WriteLine(b.Description); 
}