Converter a corda JSON em C# Objeto

Tentando converter uma string JSON em um objeto em C#. Usando um caso de teste realmente simples:

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

O problema é que o route_list nunca é definido; ele's é um objeto indefinido. Alguma ideia?

Solução

Parece que você'está tentando deserializar para um objeto bruto. Você poderia criar uma Classe que representasse o objeto que você'está convertendo para. Isto seria mais útil nos casos em que você'está lidando com objetos maiores ou com o JSON Strings.

Por exemplo:

  class Test {

      String test; 

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

  }

Então o seu código de desserialização seria:

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

Mais informações podem ser encontradas neste tutorial: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

Comentários (5)

Você provavelmente não'não quer apenas declarar rotas_list como um objeto tipo. Ele não'não tem uma propriedade .test, então você realmente vai'não vai conseguir um objeto bonito de volta. Este é um daqueles lugares onde você seria melhor definir uma classe ou uma estrutura, ou fazer uso da palavra-chave dinâmica.

Se você realmente quer que este código funcione como você o tem, você'precisará saber que o objeto retornado por DeserializeObject é um dicionário genérico de string,objeto. Aqui'é o código para fazer isso dessa forma:

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

Se você quiser usar a palavra-chave dinâmica, você pode ler como aqui.

Se você declarar uma classe ou estrutura, você pode chamar Deserialize ao invés de DeserializeObject dessa forma:

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("{ \"test\":\"some data\" }");
        Console.WriteLine(routes_list.test);

        Console.WriteLine("Done...");
        Console.ReadKey(true);
    }
}
Comentários (3)

Aqui's uma simples classe que eu empedrei a partir de vários posts.... Foi testada durante cerca de 15 minutos, mas parece* funcionar para os meus propósitos. Ele utiliza o JavascriptSerializer para fazer o trabalho, que pode ser referenciado no seu aplicativo utilizando as informações detalhadas neste post.

O código abaixo pode ser executado no LinqPad para testá-lo:

  • Clique com o botão direito do mouse na guia do seu script no LinqPad, e escolha "Query Propriedades"
  • Referências "System.Web.Extensions.dll" in "Referências Adicionais"
  • Adicionando um "Espaço de Nomes Adicional Importações" de "System.Web.Script.Serialization".

Espero que ajude!

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 jsonData { get; set; }

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

    jsonData = (IDictionary)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)curr[key];
        }
      }
    }
    catch
    {
      // Probably means an invalid path (ie object doesn't exist)
    }

    return result;
  }
}
Comentários (0)