Converteer JSON String naar C# Object

Ik probeer een JSON string om te zetten in een object in C#. Met behulp van een heel eenvoudige test case:

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

Het probleem is dat routes_list nooit ingesteld wordt; het'is een ongedefinieerd object. Iemand een idee?

Oplossing

Het lijkt erop dat je probeert te deserialiseren naar een ruw object. Je zou een Class kunnen maken die het object vertegenwoordigt waarnaar je're converteert. Dit zou het nuttigst zijn in gevallen waar je te maken hebt met grotere objecten of JSON Strings.

Bijvoorbeeld:

  class Test {

      String test; 

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

  }

Dan zou je deserialisatie code zijn:

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

Meer informatie kan gevonden worden in deze tutorial: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

Commentaren (5)

Je wilt waarschijnlijk niet zomaar routes_list declareren als een object type. Het heeft geen .test eigenschap, dus je gaat echt geen mooi object terug krijgen. Dit is een van die plaatsen waar u beter af zou zijn met het definiëren van een klasse of een struct, of gebruik maken van het dynamische sleutelwoord.

Als je echt wilt dat deze code werkt zoals je hem hebt, moet je'weten dat het object teruggegeven door DeserializeObject een generisch woordenboek van string,object is. Hier's de code om het op die manier te doen:

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

Als je het dynamische sleutelwoord wilt gebruiken, je kunt hier lezen hoe.

Als je een klasse of struct declareert, kun je Deserialize aanroepen in plaats van DeserializeObject, zoals hier:

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);
    }
}
Commentaren (3)

Hier's een eenvoudige klasse die ik uit verschillende berichten heb samengesteld.... Het'is ongeveer 15 minuten getest, maar lijkt te werken voor mijn doeleinden. Het gebruikt JavascriptSerializer om het werk te doen, waarnaar verwezen kan worden in uw app met behulp van de gedetailleerde info in deze post.

De onderstaande code kan in LinqPad worden uitgevoerd om het uit te testen door:

  • Klik met de rechtermuisknop op uw script tab in LinqPad, en kies "Query Properties"
  • Het verwijzen naar de "System.Web.Extensions.dll" in "Additional References"
  • Het toevoegen van een "Additionele Namespace Imports" van "System.Web.Script.Serialization".

Ik hoop dat het helpt!

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;
  }
}
Commentaren (0)