Wie konvertiere ich ein JSON-Objekt in ein benutzerdefiniertes C # -Objekt?


247

Gibt es eine einfache Möglichkeit, mein C # -Objekt mit dem über AJAX übergebenen JSON-Objekt zu füllen?

Dies ist das JSON-Objekt, das von der Seite mit JSON.stringify an C # WEBMETHOD übergeben wird

{
    "user": {
        "name": "asdf",
        "teamname": "b",
        "email": "c",
        "players": ["1", "2"]
    }
}

C # WebMetod Das empfängt das JSON-Objekt

[WebMethod]
public static void SaveTeam(Object user)
{

}

C # -Klasse, die die Objektstruktur des an die WebMethod übergebenen JSON-Objekts darstellt

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

69
Ich möchte hinzufügen, dass Sie json2csharp.com verwenden können , um Ihre c # -Klassen für Sie zu generieren. Vollständige Offenlegung: Ich habe diese Seite erstellt.
JonathanK


@ JonathanK Du bist mein Retter!
Matheno

Antworten:


218

Eine gute Möglichkeit, JSON in C # zu verwenden, ist JSON.NET

Schnellstarts und API-Dokumentation von JSON.NET - Die offizielle Website hilft Ihnen dabei.

Ein Beispiel für die Verwendung:

public class User
{
    public User(string json)
    {
        JObject jObject = JObject.Parse(json);
        JToken jUser = jObject["user"];
        name = (string) jUser["name"];
        teamname = (string) jUser["teamname"];
        email = (string) jUser["email"];
        players = jUser["players"].ToArray();
    }

    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

// Use
private void Run()
{
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
    User user = new User(json);

    Console.WriteLine("Name : " + user.name);
    Console.WriteLine("Teamname : " + user.teamname);
    Console.WriteLine("Email : " + user.email);
    Console.WriteLine("Players:");

    foreach (var player in user.players)
        Console.WriteLine(player);
 }

5
Dies funktioniert wie ein Champion, aber was ist, wenn ich mehrere Elemente in meinem JSON habe und eine Objektliste erstellen möchte?
Djeroen

@ Djeroen: Ich sehe zwei Möglichkeiten dafür. Wenn Elemente nicht gruppiert sind, versuchen Sie, eine Möglichkeit zum Teilen der Zeichenfolge zu finden, und wiederholen Sie den Vorgang in einer Schleife. Wenn sie gruppiert sind, machen Sie ein Objekt aus Objekten
user1011138

1
Ich bevorzuge die in anderen Antworten erwähnten Liner. IMHO.
RayLoveless

Ja, dies ist kein guter Ansatz. Der folgende Ansatz mit DeserializeObject ist viel sauberer
Andrew

207

Da wir alle One-Liner-Code lieben

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.

Wenn wir Klasse haben, verwenden Sie unten.

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(jsonString);

Keine Klasse verwendet dann dynamisch

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);

95

Um Ihre Optionen offen zu halten, wenn Sie .NET 3.5 oder höher verwenden, finden Sie hier ein Beispiel, das Sie mit Generics direkt aus dem Framework heraus verwenden können. Wie andere bereits erwähnt haben, sollten Sie JSON.net wirklich verwenden, wenn es sich nicht nur um einfache Objekte handelt.

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

Du brauchst:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

@ChristianPayne ha! Guter Punkt, ja diese sollten eingewickelt werden. Verwenden Sie im Nachhinein einfach JSON.NET!
Jammin

2
Wenn die DataContractJsonSerializer-Klasse nicht sichtbar ist, müssen Sie einen Verweis auf System.Runtime.Serialization hinzufügen, indem Sie mit der rechten Maustaste auf die Referenzen in der Lösung klicken, die Registerkarte .NET auswählen und System.Runtime.Serialization
DanKodi

1
Ein Szenario, in dem dieses kaputt geht. Wenn Ihr JSON-Objekt Eigenschaften in einfachen Anführungszeichen darstellt, schlägt diese Funktion fehl. zB war es nicht möglich, {'Betreff': 'E-Mail: Webbenutzer-Aktivitätsprotokoll11', 'EmbedAsImage': true} zu analysieren, aber es konnte {"Betreff": "E-Mail: Webbenutzer-Aktivitätsprotokoll11", "EmbedAsImage" analysieren : true}
dreamerkumar

Außerdem musste ich meine einfache Klasse mit DataContract- und DataMember-Attributen dekorieren. Ohne wird es nicht analysiert.
Dreamerkumar

Im Gegensatz zu Vishal hat eine POCO-Klasse für mich perfekt funktioniert ... +1, da dadurch eine Abhängigkeit von JSON.NET vermieden wird.
Dunc

54

In Anbetracht Ihres Codebeispiels sollten Sie nichts anderes tun müssen.

Wenn Sie diese JSON-Zeichenfolge an Ihre Webmethode übergeben, wird die JSON-Zeichenfolge automatisch analysiert und ein aufgefülltes Benutzerobjekt als Parameter für Ihre SaveTeam-Methode erstellt.

Im Allgemeinen können Sie die JavascriptSerializerKlasse wie folgt verwenden oder für mehr Flexibilität eines der verschiedenen Json-Frameworks (Jayrock JSON ist gut) für eine einfache JSON-Manipulation verwenden.

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse); 

1
Ich denke, Sie müssen einen ienumerable Typ verwenden (also in diesem Beispiel Liste <Benutzer>)
Dragouf

Wie können wir deserialisieren, wenn es Unteransichtsmodell enthält
SrinivasNaidu

1
Für diejenigen, die suchen, müssen Sie auf die System.Web.ExtensionsAssembly verweisen und ein hinzufügen using System.Web.Script.Serialization, um an die zu gelangen. JavaScriptSerializerSobald Sie dies tun, scheint dies der sauberste Weg zu sein, Ihre jsonZeichenfolgen in konkrete c # -Klassen zu deserialisieren .
Serj Sagan

41

Eine andere wirklich einfache Lösung ist die Verwendung der Bibliothek Newtonsoft.Json:

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

Wenn das User-Objekt jedoch andere JSon-Daten in der Eigenschaft hat, schlägt dies fehl ...
gumuruh

@gumuruh Ich glaube, ich habe deine Aussage nicht verstanden. Wenn Sie ein komplexes Objekt haben, bei dem es sich bei den Eigenschaften um andere komplexe Objekte handelt, werden diese ebenfalls konvertiert, sofern Ihre Json-Zeichenfolge die Daten korrekt enthält.
Daniel

33

Die folgenden 2 Beispiele verwenden entweder

  1. JavaScriptSerializer unter System.Web.Script.Serialization Or. En
  2. Json.Decode unter System.Web.Helpers

Beispiel 1: Verwenden von System.Web.Script.Serialization

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void Test()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            dynamic jsonObject = serializer.Deserialize<dynamic>(json);

            dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values
            x = jsonObject["user"]["name"]; // result is asdf
            x = jsonObject["user"]["players"]; // result is object[] players with its values
        }
    }
}

Verwendung: JSON-Objekt zu benutzerdefiniertem C # -Objekt

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJavaScriptSerializer()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<dynamic>(json);
            name = (string)jsonObject["user"]["name"];
            teamname = (string)jsonObject["user"]["teamname"];
            email = (string)jsonObject["user"]["email"];
            players = jsonObject["user"]["players"];
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Beispiel 2: Verwenden von System.Web.Helpers

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            dynamic jsonObject = Json.Decode(json);

            dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values
            x = jsonObject.user.name; // result is asdf
            x = jsonObject.user.players; // result is dynamic json array players with its values
        }
    }
}

Verwendung: JSON-Objekt zu benutzerdefiniertem C # -Objekt

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            var jsonObject = Json.Decode(json);
            name = (string)jsonObject.user.name;
            teamname = (string)jsonObject.user.teamname;
            email = (string)jsonObject.user.email;
            players = (DynamicJsonArray) jsonObject.user.players;
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Dieser Code erfordert das Hinzufügen des System.Web.Helpers-Namespace in,

% ProgramFiles% \ Microsoft ASP.NET \ ASP.NET-Webseiten {VERSION} \ Assemblies \ System.Web.Helpers.dll

Oder

% ProgramFiles (x86)% \ Microsoft ASP.NET \ ASP.NET-Webseiten {VERSION} \ Assemblies \ System.Web.Helpers.dll

Hoffe das hilft!


Dies ist eine sehr gute Antwort, aber das Schwierige ist, dass Sie mit dynamicTypen keine echte Typprüfung erhalten. Wenn Ihr JSON "Name" : "Ahmed"beispielsweise "Name" in Ihrem C # -Code enthält und Sie diesen falsch eingeben, handelt es sich um einen Laufzeitfehler (bleh).
Jess

Vielen Dank! Bitte aktualisieren Sie die Antwort, um anzugeben, dass Sie für Beispiel 1 auf System.Web.Extensions.dll verweisen müssen
Valamas

1
super tolle Antwort, die dynamische Eingabe funktioniert auch mit json.net v6.0.6!
stackuser83

7
public static class Utilities
{
    public static T Deserialize<T>(string jsonString)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {    
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

Weitere Informationen finden Sie unter folgendem Link: http://ishareidea.blogspot.in/2012/05/json-conversion.html

Über DataContractJsonSerializer Class Sie können hier lesen .


5

Die Verwendung von JavaScriptSerializer () ist weniger streng als die generische Lösung: public static T Deserialize (string json)

Dies kann nützlich sein, wenn Sie json an den Server übergeben, der nicht genau der Objektdefinition entspricht, in die Sie konvertieren möchten.



1

JSON.Net ist die beste Wahl, aber je nach Form der Objekte und ob es kreisförmige Abhängigkeiten gibt, können Sie JavaScriptSerializer oder DataContractSerializer verwenden.



1

JavaScript Serializer: erfordert using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T>
{
    private readonly JavaScriptSerializer serializer;

    public JavaScriptSerializerDeSerializer()
    {
        this.serializer = new JavaScriptSerializer();
    }

    public string Serialize(T t)
    {
        return this.serializer.Serialize(t);
    }

    public T Deseralize(string stringObject)
    {
        return this.serializer.Deserialize<T>(stringObject);
    }
}

Data Contract Serializer: erfordert using System.Runtime.Serialization.Json; - Der generische Typ T sollte im Data Contract besser serialisierbar sein

public class JsonSerializerDeserializer<T> where T : class
{
    private readonly DataContractJsonSerializer jsonSerializer;

    public JsonSerializerDeserializer()
    {
        this.jsonSerializer = new DataContractJsonSerializer(typeof(T));
    }

    public string Serialize(T t)
    {
        using (var memoryStream = new MemoryStream())
        {
            this.jsonSerializer.WriteObject(memoryStream, t);
            memoryStream.Position = 0;
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }

    public T Deserialize(string objectString)
    {
        using (var ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes((objectString))))
        {
            return (T)this.jsonSerializer.ReadObject(ms);
        }
    }
}

0

Anstatt nur als Objekt zu senden.

Erstellen Sie eine öffentliche Klasse von Eigenschaften, auf die zugegriffen werden kann, und senden Sie die Daten an die Webmethode.

[WebMethod]
public static void SaveTeam(useSomeClassHere user)
{
}

Verwenden Sie im Ajax-Aufruf dieselben Parameternamen, um Daten zu senden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.