Wie verwandle ich ein C # -Objekt in .NET in eine JSON-Zeichenfolge?

944

Ich habe Klassen wie diese:

class MyDate
{
    int year, month, day;
}

class Lad
{
    string firstName;
    string lastName;
    MyDate dateOfBirth;
}

Und ich möchte ein LadObjekt wie folgt in einen JSON- String verwandeln :

{
    "firstName":"Markoff",
    "lastName":"Chaney",
    "dateOfBirth":
    {
        "year":"1901",
        "month":"4",
        "day":"30"
    }
}

(ohne die Formatierung). Ich habe diesen Link gefunden , aber er verwendet einen Namespace, der nicht in .NET 4 enthalten ist . Ich habe auch von JSON.NET gehört , aber die Website scheint momentan nicht verfügbar zu sein, und ich bin nicht daran interessiert, externe DLL-Dateien zu verwenden.

Gibt es neben dem manuellen Erstellen eines JSON- String- Writers noch andere Optionen ?

Hui
quelle
2
JSON.net kann hier geladen werden Eine andere und schnellere (wie sie sagen - ich habe es nicht selbst getestet) Lösung ist ServiceStack.Text Ich würde nicht empfehlen, Ihren eigenen JSON-Parser zu rollen. Es wird wahrscheinlich langsamer und fehleranfälliger sein oder Sie müssen viel Zeit investieren.
Zebi
Ja. C # hat einen Typ namens JavaScriptSerializer
Glenn Ferrie
Mögliches Duplikat von Generics / JSON JavaScriptSerializer C #
Filip Ekberg
2
Hm .. soweit ich sehen kann sollten Sie in der Lage sein: msdn.microsoft.com/en-us/library/… Das ist laut MSDN-Seite auch in .Net 4.0 enthalten. Sie sollten in der Lage sein, die Methode Serialize (Object obj) zu verwenden: msdn.microsoft.com/en-us/library/bb292287.aspx Vermisse ich hier etwas? Übrigens. Ihr Link scheint ein Code zu sein und kein Link
Holger
Ganz zu schweigen davon, dass es keine Abhängigkeiten von den System.Web.Xyz-Namespaces gibt ...
Dave Jellison

Antworten:

899

Sie können die JavaScriptSerializerKlasse verwenden (Verweis hinzufügen auf System.Web.Extensions):

using System.Web.Script.Serialization;
var json = new JavaScriptSerializer().Serialize(obj);

Ein vollständiges Beispiel:

using System;
using System.Web.Script.Serialization;

public class MyDate
{
    public int year;
    public int month;
    public int day;
}

public class Lad
{
    public string firstName;
    public string lastName;
    public MyDate dateOfBirth;
}

class Program
{
    static void Main()
    {
        var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = new JavaScriptSerializer().Serialize(obj);
        Console.WriteLine(json);
    }
}
Darin Dimitrov
quelle
95
Beachten Sie bitte, dass Microsoft vorschlägt, JSON.net anstelle dieser Lösung zu verwenden. Ich denke, dass diese Antwort unangemessen wurde. Schauen Sie sich die Antwort von Willsteel an. Quelle: https://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer.aspx .
Rzelek
9
@DarinDimitrov Sie sollten einen Hinweis zu JSON.net hinzufügen. Microsoft empfiehlt es über JavaScriptSerializer: msdn.microsoft.com/en-us/library/... Sie auch einen Hinweis hinzufügen könnte msdn.microsoft.com/en-us/library/... die der Rahmen enthalten Ansatz ist
mafii
hier ist Online - Tool Ihre konvertieren classeszu jsonFormat, Hoffnung , jemand hilft.
Shaijut
6
Warum sollte Microsoft eine Lösung von Drittanbietern empfehlen? Der Wortlaut ist ebenfalls sehr seltsam: "Json.NET sollte als Serialisierung und Deserialisierung verwendet werden. Bietet Serialisierungs- und Deserialisierungsfunktionen für AJAX-fähige Anwendungen."
Beschützer ein
1
Nur ein Hinweis System.Web.Extensions, auf den Sie verweisen müssen, müssen Sie auf Ihrem System haben ASP.NET AJAX 1.0oder ASP.NET 3.5installiert haben . Bitte sehen Sie diese stackoverflow.com/questions/7723489/…
Sisir
1056

Da lieben wir alle Einzeiler

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

Newtonsoft.Json.JsonConvert.SerializeObject(new {foo = "bar"})

Dokumentation: Serialisieren und Deserialisieren von JSON

mschmoock
quelle
134
Newtonsoft Serializer ist viel schneller und anpassbarer als eingebaut. Es wird dringend empfohlen, ihn zu verwenden. Danke für die Antwort @willsteel
Andrei
8
@ JosefPfleger Der Preis gilt für JSON.NET Schema, nicht für JSON.NET, den regulären Serializer, MIT
David Cumps
1
Meine Tests haben gezeigt, dass Newtonsoft langsamer als die JavaScriptSerializer-Klasse ist. (.NET 4.5.2)
Nemke
31
Wenn Sie die MSDN-Dokumentation für JavaScriptSerializer lesen , heißt es direkt, dass Sie JSON.net verwenden.
Dsghi
3
@JosefPfleger Newtionsoft JSON.net ist MIT-lizenziert ... Sie können Änderungen vornehmen und es weiterverkaufen, wie Sie möchten. Auf ihrer Preisseite geht es um kommerziellen technischen Support und einige Schema-Validatoren.
cb88
95

Verwenden Sie die Json.Net- Bibliothek, und laden Sie sie vom Nuget Packet Manager herunter.

Serialisierung zu Json String:

 var obj = new Lad
        {
            firstName = "Markoff",
            lastName = "Chaney",
            dateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };

var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(obj);

Deserialisieren zum Objekt:

var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<Lad>(jsonString );
Gokulan PH
quelle
57

Verwenden Sie die DataContractJsonSerializerKlasse: MSDN1 , MSDN2 .

Mein Beispiel: HIER .

Im Gegensatz dazu kann es Objekte aus einer JSON-Zeichenfolge auch sicher deserialisieren JavaScriptSerializer. Aber ich persönlich bevorzuge immer noch Json.NET .

Edgar
quelle
1
Auf dieser Seite werden noch keine Beispiele angezeigt , aber hier einige auf MSDN und anderswo -> der letzte verwendet Erweiterungsmethoden, um Einzeiler zu erzielen.
Cristian Diaconescu
Oh, ich habe den 2. MSDN-Link verpasst :)
Cristian Diaconescu
2
Es werden keine einfachen Klassen serialisiert. Der gemeldete Fehler "Markieren Sie ihn möglicherweise mit dem DataContractAttribute-Attribut und markieren Sie alle zu serialisierenden Mitglieder mit dem DataMemberAttribute-Attribut. Wenn es sich bei dem Typ um eine Sammlung handelt, sollten Sie ihn mit dem CollectionDataContractAttribute markieren."
Michael Freidgeim
@MichaelFreidgeim Richtig, Sie müssen Eigenschaften in der Klasse, die Sie serialisieren möchten, mit Attributen markieren. Datacontractdatamember
Edgar
1
@ MichaelFreidgeim Was besser ist, hängt von den Anforderungen ab. Mit den Attributen können Sie konfigurieren, wie die Eigenschaft serialisiert wird.
Edgar
24

Sie können dies mit Newtonsoft.json erreichen. Installieren Sie Newtonsoft.json von NuGet. Und dann:

using Newtonsoft.Json;

var jsonString = JsonConvert.SerializeObject(obj);
Waleed Naveed
quelle
22

Wooou! Wirklich besser mit einem JSON-Framework :)

Hier ist mein Beispiel mit Json.NET ( http://james.newtonking.com/json ):

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json;
using System.IO;

namespace com.blogspot.jeanjmichel.jsontest.model
{
    public class Contact
    {
        private Int64 id;
        private String name;
        List<Address> addresses;

        public Int64 Id
        {
            set { this.id = value; }
            get { return this.id; }
        }

        public String Name
        {
            set { this.name = value; }
            get { return this.name; }
        }

        public List<Address> Addresses
        {
            set { this.addresses = value; }
            get { return this.addresses; }
        }

        public String ToJSONRepresentation()
        {
            StringBuilder sb = new StringBuilder();
            JsonWriter jw = new JsonTextWriter(new StringWriter(sb));

            jw.Formatting = Formatting.Indented;
            jw.WriteStartObject();
            jw.WritePropertyName("id");
            jw.WriteValue(this.Id);
            jw.WritePropertyName("name");
            jw.WriteValue(this.Name);

            jw.WritePropertyName("addresses");
            jw.WriteStartArray();

            int i;
            i = 0;

            for (i = 0; i < addresses.Count; i++)
            {
                jw.WriteStartObject();
                jw.WritePropertyName("id");
                jw.WriteValue(addresses[i].Id);
                jw.WritePropertyName("streetAddress");
                jw.WriteValue(addresses[i].StreetAddress);
                jw.WritePropertyName("complement");
                jw.WriteValue(addresses[i].Complement);
                jw.WritePropertyName("city");
                jw.WriteValue(addresses[i].City);
                jw.WritePropertyName("province");
                jw.WriteValue(addresses[i].Province);
                jw.WritePropertyName("country");
                jw.WriteValue(addresses[i].Country);
                jw.WritePropertyName("postalCode");
                jw.WriteValue(addresses[i].PostalCode);
                jw.WriteEndObject();
            }

            jw.WriteEndArray();

            jw.WriteEndObject();

            return sb.ToString();
        }

        public Contact()
        {
        }

        public Contact(Int64 id, String personName, List<Address> addresses)
        {
            this.id = id;
            this.name = personName;
            this.addresses = addresses;
        }

        public Contact(String JSONRepresentation)
        {
            //To do
        }
    }
}

Die Prüfung:

using System;
using System.Collections.Generic;
using com.blogspot.jeanjmichel.jsontest.model;

namespace com.blogspot.jeanjmichel.jsontest.main
{
    public class Program
    {
        static void Main(string[] args)
        {
            List<Address> addresses = new List<Address>();
            addresses.Add(new Address(1, "Rua Dr. Fernandes Coelho, 85", "15º andar", "São Paulo", "São Paulo", "Brazil", "05423040"));
            addresses.Add(new Address(2, "Avenida Senador Teotônio Vilela, 241", null, "São Paulo", "São Paulo", "Brazil", null));

            Contact contact = new Contact(1, "Ayrton Senna", addresses);

            Console.WriteLine(contact.ToJSONRepresentation());
            Console.ReadKey();
        }
    }
}

Das Ergebnis:

{
  "id": 1,
  "name": "Ayrton Senna",
  "addresses": [
    {
      "id": 1,
      "streetAddress": "Rua Dr. Fernandes Coelho, 85",
      "complement": "15º andar",
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": "05423040"
    },
    {
      "id": 2,
      "streetAddress": "Avenida Senador Teotônio Vilela, 241",
      "complement": null,
      "city": "São Paulo",
      "province": "São Paulo",
      "country": "Brazil",
      "postalCode": null
    }
  ]
}

Jetzt werde ich die Konstruktormethode implementieren, die eine JSON-Zeichenfolge empfängt und die Felder der Klasse auffüllt.

Jean J. Michel
quelle
1
Guter Beitrag, dies ist der aktuellste Weg, dies zu tun.
MatthewD
20

Ein neuer JSON-Serializer ist im System.Text.JsonNamespace verfügbar . Es ist im gemeinsam genutzten .NET Core 3.0-Framework enthalten und in einem NuGet-Paket für Projekte enthalten, die auf .NET Standard oder .NET Framework oder .NET Core 2.x abzielen.

Beispielcode:

using System;
using System.Text.Json;

public class MyDate
{
    public int year { get; set; }
    public int month { get; set; }
    public int day { get; set; }
}

public class Lad
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public MyDate DateOfBirth { get; set; }
}

class Program
{
    static void Main()
    {
        var lad = new Lad
        {
            FirstName = "Markoff",
            LastName = "Chaney",
            DateOfBirth = new MyDate
            {
                year = 1901,
                month = 4,
                day = 30
            }
        };
        var json = JsonSerializer.Serialize(lad);
        Console.WriteLine(json);
    }
}

In diesem Beispiel haben die zu serialisierenden Klassen eher Eigenschaften als Felder. Der System.Text.JsonSerializer serialisiert derzeit keine Felder.

Dokumentation:

tdykstra
quelle
9

Wenn sie nicht sehr groß sind, exportieren Sie sie wahrscheinlich als JSON.

Dies macht es auch für alle Plattformen portabel.

using Newtonsoft.Json;

[TestMethod]
public void ExportJson()
{
    double[,] b = new double[,]
        {
            { 110,  120,  130,  140, 150 },
            {1110, 1120, 1130, 1140, 1150},
            {1000,    1,   5,     9, 1000},
            {1110,    2,   6,    10, 1110},
            {1220,    3,   7,    11, 1220},
            {1330,    4,   8,    12, 1330}
        };

    string jsonStr = JsonConvert.SerializeObject(b);

    Console.WriteLine(jsonStr);

    string path = "X:\\Programming\\workspaceEclipse\\PyTutorials\\src\\tensorflow_tutorials\\export.txt";

    File.WriteAllText(path, jsonStr);
}
user8426627
quelle
8

Wenn Sie sich in einem ASP.NET MVC-Webcontroller befinden, ist dies so einfach wie:

string ladAsJson = Json(Lad);

Ich kann nicht glauben, dass niemand dies erwähnt hat.

Micahhoover
quelle
1
Ich erhalte die Fehlermeldung, dass jsonresult nicht in einen String umgewandelt werden kann.
csga5000
Es wird mit impliziter Typisierung kompiliert: var ladAsJson = Json (Lad).
Ewomack
3

Ich würde für den JSON Serializer von ServiceStack stimmen:

using ServiceStack.Text

string jsonString = new { FirstName = "James" }.ToJson();

Es ist auch der schnellste JSON-Serializer für .NET: http://www.servicestack.net/benchmarks/

James
quelle
4
Das sind dort sehr alte Benchmarks. Ich habe gerade alle drei aktuellen Versionen von Newtonsoft, ServiceStack und JavaScriptSerializer getestet und derzeit ist Newtonsoft die schnellste. Das machen sie alle ziemlich schnell.
Michael Logutov
1
ServiceStack scheint nicht kostenlos zu sein.
Joelnet
@joelnet das ist jetzt der Fall, war aber kostenlos bei der Beantwortung der Frage. Es ist jedoch kostenlos für kleine Websites und ich benutze es immer noch, obwohl es bezahlt wird, es ist ein hervorragendes Framework.
James
Einige Benchmarks hier, obwohl es keine für die Serialisierung allein gibt: docs.servicestack.net/real-world-performance
JohnLBevan
3

Verwenden Sie den folgenden Code zum Konvertieren von XML in JSON.

var json = new JavaScriptSerializer().Serialize(obj);
Hithesh
quelle
3

Verwenden Sie diese Tools zum Generieren einer C # -Klasse und verwenden Sie dann diesen Code, um Ihr Objekt zu serialisieren:

 var json = new JavaScriptSerializer().Serialize(obj);
Artem Polishchuk
quelle
3

So einfach ist das (es funktioniert auch für dynamische Objekte (Typ Objekt)):

string json = new
System.Web.Script.Serialization.JavaScriptSerializer().Serialize(MYOBJECT);
MarzSocks
quelle
Unter Web gibt es kein Standardskript. :(
M am
Sie suchen dies: msdn.microsoft.com/en-us/library/…
MarzSocks
Ich habe das irgendwie versucht, aber nein. Skript Ich denke, ich sollte es als Referenz hinzufügen. Also vielen Dank
M am
0

Serializer

 public static void WriteToJsonFile<T>(string filePath, T objectToWrite, bool append = false) where T : new()
{
        var contentsToWriteToFile = JsonConvert.SerializeObject(objectToWrite, new JsonSerializerSettings
        {
            Formatting = Formatting.Indented,
        });
        using (var writer = new StreamWriter(filePath, append))
        {
            writer.Write(contentsToWriteToFile);
        }
}

Objekt

namespace MyConfig
{
    public class AppConfigurationSettings
    {
        public AppConfigurationSettings()
        {
            /* initialize the object if you want to output a new document
             * for use as a template or default settings possibly when 
             * an app is started.
             */
            if (AppSettings == null) { AppSettings=new AppSettings();}
        }

        public AppSettings AppSettings { get; set; }
    }

    public class AppSettings
    {
        public bool DebugMode { get; set; } = false;
    }
}

Implementierung

var jsonObject = new AppConfigurationSettings();
WriteToJsonFile<AppConfigurationSettings>(file.FullName, jsonObject);

Ausgabe

{
  "AppSettings": {
    "DebugMode": false
  }
}
dynamiclynk
quelle