JSON-String in C # -Objekt konvertieren

183

Versuch, eine JSON-Zeichenfolge in ein Objekt in C # zu konvertieren. Verwenden eines wirklich einfachen Testfalls:

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

Das Problem ist, dass route_list niemals gesetzt wird. Es ist ein undefiniertes Objekt. Irgendwelche Ideen?

Justin
quelle
1
@ Greg: Ich empfehle die JavaScriptSerializerVersion von over MS, da sie nichts anderes als die benutzerdefinierte JSON-Formatierung von WCF akzeptiert (z. B. Datumsfelder, die wie Datumsangaben aussehen, aber nicht in DATE () enthalten sind, schlagen kläglich fehl)
Brad Christie
Schauen Sie sich auch dieses Parsing von JSON-Objekten mit JavascriptSerializer im .NET- Artikel an, der eigentlich ein großartiges Tutorial ist.
Scatmoi
Woher bekommen Sie JavaScriptSerializer? Es wird in meinem C # .NET 3.5-Projekt nicht erkannt.
B. Clay Shannon
1
@B. Clay Shannon Dies löste es für mich stackoverflow.com/questions/7000811/…
Fuzzybear

Antworten:

127

Es sieht so aus, als würden Sie versuchen, ein Rohobjekt zu deserialisieren. Sie können eine Klasse erstellen, die das Objekt darstellt, in das Sie konvertieren. Dies ist am nützlichsten in Fällen, in denen Sie mit größeren Objekten oder JSON-Strings arbeiten.

Zum Beispiel:

  class Test {

      String test; 

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

  }

Dann wäre Ihr Deserialisierungscode:

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

Weitere Informationen finden Sie in diesem Tutorial: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx

jmort253
quelle
1
In spitzen Artikeln werden jedoch Autoproperties verwendet. Erwähnenswert ist auch.
Ivan Kochurkin
11
Entschuldigung, aber dieses Codebeispiel funktioniert nicht. DeserializeObject gibt eine Ausnahme. Verwenden Sie var route_list = serializer.Deserialize <Test> ("{" test ":" einige Daten "}"); stattdessen. Außerdem müssen Sie get / setTest () nicht benötigen, und String test sollte öffentlich sein. Dies sieht eher nach Java als nach C # aus.
Dvallejo
Wie Dan Vallejo erwähnte, ist dies eine falsche Lösung. Immerhin gibt setTest (String test) nicht zurück, was ebenfalls ein Kompilierungsfehler ist.
Payam
1
Kann auch Folgendes verwenden: json_serializer.Deserialize <Test> ("{" test ":" einige Daten "}"); // anstelle von (Test) json_serializer .....
Bashar Abu Shamaa
1
Wenn Sie sich über das Format Ihres Klassenobjekts nicht sicher sind, versuchen Sie diesen Link . Es übersetzt Ihren Json-String in die richtigen Klassen. Hat mir eine Menge Zeit gespart!
Jade290
228

Sie können die Newtownsoft.Json-Bibliothek auch wie folgt verwenden:

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

Wo Tist Ihr Objekttyp, der mit Ihrer JSON-Zeichenfolge übereinstimmt?

tripletdad99
quelle
3
Es ist so einfach und ich habe so lange darüber nachgedacht, wie das geht.
Maracuja-Saft
58

Sie möchten wahrscheinlich nicht nur route_list als objectTyp deklarieren . Es hat keine .test-Eigenschaft, so dass Sie wirklich kein schönes Objekt zurückbekommen. Dies ist einer der Orte, an denen Sie besser eine Klasse oder eine Struktur definieren oder das dynamische Schlüsselwort verwenden sollten.

Wenn Sie wirklich möchten, dass dieser Code so funktioniert, wie Sie ihn haben, müssen Sie wissen, dass das von DeserializeObject zurückgegebene Objekt ein generisches Wörterbuch aus Zeichenfolge und Objekt ist. Hier ist der Code, um es so zu machen:

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

Wenn Sie das dynamische Schlüsselwort verwenden möchten, können Sie hier lesen, wie .

Wenn Sie eine Klasse oder Struktur deklarieren, können Sie Deserialize anstelle von DeserializeObject wie folgt aufrufen:

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);
    }
}
mattmc3
quelle
Tun: json_serializer = neuer JavaScriptSerializer (); object route_list = (IDictionary <string, object>) json_serializer.DeserializeObject ("{" test ":" einige Daten hier "}"); Das Abrufen von 'route_list' ist im aktuellen Kontext noch nicht vorhanden.
Justin
1
Nicht benutzen object routes_list. Verwenden Sie varoder wiederholen Sie sich explizit und deklarieren Sie route_list als IDictionary <string, object>.
Mattmc3
31

Verwenden eines dynamischen Objekts mit JavaScriptSerializer.

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

//test Result = "some data"
İbrahim Özbölük
quelle
19

Newtonsoft ist schneller als der Java Script Serializer. ... dies hängt vom Newtonsoft NuGet-Paket ab, das beliebt und besser als der Standard-Serializer ist.

Einzeilencode-Lösung.

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

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);
MSTdev
quelle
15

Hier ist eine einfache Klasse, die ich aus verschiedenen Beiträgen zusammengeschustert habe. Sie wurde ungefähr 15 Minuten lang getestet, scheint aber für meine Zwecke zu funktionieren. Es wird verwendet JavascriptSerializer, um die Arbeit zu erledigen, auf die in Ihrer App anhand der in diesem Beitrag beschriebenen Informationen verwiesen werden kann .

Der folgende Code kann in LinqPad ausgeführt werden, um ihn zu testen:

  • Klicken Sie mit der rechten Maustaste auf Ihre Skriptregisterkarte in LinqPad und wählen Sie "Abfrageeigenschaften".
  • Verweisen auf die "System.Web.Extensions.dll" in "Zusätzliche Referenzen"
  • Hinzufügen eines "zusätzlichen Namespace-Imports" von "System.Web.Script.Serialization".

Ich hoffe es hilft!

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;
  }
}
Brad Parks
quelle
14

Sie können Ihre Anforderung einfach mithilfe der Newtonsoft.Json-Bibliothek erfüllen. Ich schreibe das eine Beispiel unten auf, schau es dir an.

Klasse für den Objekttyp, den Sie erhalten:

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

}

Code:

static void Main(string[] args)
{

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

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

      Console.ReadKey();
}

Dies ist eine sehr einfache Möglichkeit, Ihren JSON zu analysieren.

Mirza Danish Baig
quelle
11

Wie tripletdad99 sagte

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

Wenn Sie jedoch kein zusätzliches Objekt erstellen möchten, können Sie es Dictionarystattdessen erstellen

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);
stanimirsp
quelle
Dies ist nützlich, wenn Sie dann Parameter an Url.Action (Aktion, Controller, Ergebnis) übergeben
Lapenkov Vladimir
8

Fügen Sie diese DDL hinzu, um auf Ihr Projekt zu verweisen: System.Web.Extensions.dll

Verwenden Sie diesen Namespace: using System.Web.Script.Serialization;

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);
Thulasiram
quelle
6

Kopieren Sie Ihren Json und fügen Sie ihn in das Textfeld auf json2csharp ein und klicken Sie auf die Schaltfläche Generieren.

Eine cs- Klasse wird unter Verwendung dieser cs-Datei wie unten generiert

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

Wo RootObjectist der Name der generierten CS- Datei ?

Islam
quelle
4

Eine weitere schnelle und einfache Möglichkeit, diese Schritte halbautomatisch durchzuführen, besteht darin:

  1. Nehmen Sie den JSON, den Sie analysieren möchten, und fügen Sie ihn hier ein: https://app.quicktype.io/ . Ändern Sie die Sprache in der Dropdown-Liste in C #.
  2. Aktualisieren Sie den Namen oben links auf Ihren Klassennamen. Der Standardwert ist "Willkommen".
  3. Gehen Sie im Visual Studio zu Website -> Pakete verwalten und verwenden Sie NuGet, um Json.Net von Newtonsoft hinzuzufügen.
  4. app.quicktype.io hat Serialisierungsmethoden basierend auf Newtonsoft generiert. Alternativ können Sie jetzt Code verwenden wie:

    WebClient-Client = neuer WebClient ();

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

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

Jason Hitchings
quelle
Link nicht mehr gültig
Myles J
Danke Myles J, ich habe auf eine neue Seite aktualisiert, die anscheinend gut funktioniert.
Jason Hitchings
0

Konvertieren Sie eine JSON-Zeichenfolge in ein Objekt in C #. Mit dem folgenden Testfall .. es hat bei mir funktioniert. Hier ist " MenuInfo " mein C # -Klassenobjekt .

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);
Bhaskar
quelle
0

Zuerst müssen Sie eine Bibliothek einschließen wie:

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);
}
Muhammad Zahid
quelle