Μετατροπή συμβολοσειράς JSON σε αντικείμενο C#

Προσπαθώ να μετατρέψω ένα αλφαριθμητικό JSON σε αντικείμενο στη C#. Χρησιμοποιώντας μια πολύ απλή περίπτωση δοκιμής:

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

Το πρόβλημα είναι ότι το routes_list δεν τίθεται ποτέ- είναι ένα απροσδιόριστο αντικείμενο. Καμία ιδέα;

Λύση

Φαίνεται ότι προσπαθείτε να αποδιαταχθείτε σε ένα ακατέργαστο αντικείμενο. Θα μπορούσατε να δημιουργήσετε μια Κλάση που αντιπροσωπεύει το αντικείμενο στο οποίο μετατρέπετε. Αυτό θα ήταν πιο χρήσιμο σε περιπτώσεις όπου έχετε να κάνετε με μεγαλύτερα αντικείμενα ή συμβολοσειρές JSON.

Για παράδειγμα:

  class Test {

      String test; 

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

  }

Τότε ο κώδικάς σας για την αποδιάταξη θα είναι:

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

Περισσότερες πληροφορίες μπορείτε να βρείτε σε αυτό το σεμινάριο: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

Σχόλια (5)

Πιθανόν να μην θέλετε να δηλώσετε την routes_list ως τύπο "αντικειμένου". Δεν έχει την ιδιότητα .test, οπότε πραγματικά δεν πρόκειται να πάρετε πίσω ένα ωραίο αντικείμενο. Αυτό είναι ένα από εκείνα τα σημεία όπου θα ήταν καλύτερα να ορίσετε μια κλάση ή μια δομή, ή να κάνετε χρήση της λέξης-κλειδί dynamic.

Αν θέλετε πραγματικά αυτός ο κώδικας να λειτουργεί όπως τον έχετε, θα πρέπει να γνωρίζετε ότι το αντικείμενο που επιστρέφει η DeserializeObject είναι ένα γενικό λεξικό string,object. Εδώ'είναι ο κώδικας για να το κάνετε με αυτόν τον τρόπο:

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

Αν θέλετε να χρησιμοποιήσετε τη λέξη-κλειδί dynamic, μπορείτε να διαβάσετε πώς εδώ.

Αν δηλώσετε μια κλάση ή μια δομή, μπορείτε να καλέσετε το Deserialize αντί για το DeserializeObject, όπως παρακάτω:

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);
    }
}
Σχόλια (3)

Εδώ'είναι μια απλή κλάση που συναρμολόγησα από διάφορες αναρτήσεις.... Έχει δοκιμαστεί για περίπου 15 λεπτά, αλλά φαίνεται να λειτουργεί για τους σκοπούς μου. Χρησιμοποιεί το JavascriptSerializer για να κάνει τη δουλειά, το οποίο μπορεί να αναφερθεί στην εφαρμογή σας χρησιμοποιώντας τις πληροφορίες που περιγράφονται λεπτομερώς σε αυτό το post.

Ο παρακάτω κώδικας μπορεί να εκτελεστεί στο LinqPad για να τον δοκιμάσετε από:

  • Δεξί κλικ στην καρτέλα του σεναρίου σας στο LinqPad και επιλέγοντας "Query Properties&quot,
  • Αναφορά στο "System.Web.Extensions.dll" στο "Πρόσθετες αναφορές"
  • Προσθήκη ενός "Additional Namespace Imports" της "System.Web.Script.Serialization".

Ελπίζω να βοηθήσει!

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;
  }
}
Σχόλια (0)