Serialisierung einer Liste an JSON

182

Ich habe ein Objektmodell, das so aussieht:

public MyObjectInJson
{
   public long ObjectID {get;set;}
   public string ObjectInJson {get;set;}
}

Die Eigenschaft ObjectInJsonist eine bereits serialisierte Version eines Objekts, das verschachtelte Listen enthält. Im Moment serialisiere ich die Liste MyObjectInJsonmanuell wie folgt:

StringBuilder TheListBuilder = new StringBuilder();

TheListBuilder.Append("[");
int TheCounter = 0;

foreach (MyObjectInJson TheObject in TheList)
{
  TheCounter++;
  TheListBuilder.Append(TheObject.ObjectInJson);

  if (TheCounter != TheList.Count())
  {
    TheListBuilder.Append(",");
  }
}
TheListBuilder.Append("]");

return TheListBuilder.ToString();

Ich frage mich, ob ich diese Art von gefährlichem Code durch ersetzen JavascriptSerializerund die gleichen Ergebnisse erzielen kann. Wie würde ich das machen?

Vielen Dank.

frenchie
quelle
Beachten Sie, dass Sie in einem WPF-Projekt einen Verweis hinzufügen müssen, um FolgendesSystem.Web.Extensions zu verwenden System.Web.Script.Serialization: stackoverflow.com/a/18746092/1599699 stackoverflow.com/a/19299695/1599699
Andrew

Antworten:

337

Bei Verwendung von .Net Core 3.0 oder höher;

Standardmäßig wird die integrierte System.Text.JsonParser-Implementierung verwendet.

z.B

using System.Text.Json;

var json = JsonSerializer.Serialize(aList);

Alternativ stehen andere, weniger gängige Optionen wie Utf8Json- Parser und Jil zur Verfügung : Diese bieten möglicherweise eine überlegene Leistung , wenn Sie sie wirklich benötigen, müssen Sie jedoch die entsprechenden Pakete installieren.

Wenn Sie mit .Net Core 2.2 oder früher nicht weiterkommen;

Standardmäßig wird Newtonsoft JSON.Net als JSON-Parser erster Wahl verwendet.

z.B

using Newtonsoft.Json;

var json = JsonConvert.SerializeObject(aList);

Möglicherweise müssen Sie zuerst das Paket installieren.

PM> Install-Package Newtonsoft.Json

Weitere Informationen finden Sie in der Antwort, aus der diese Informationen stammen .

Nur als Referenz war dies die ursprüngliche Antwort vor vielen Jahren;

// you need to reference System.Web.Extensions

using System.Web.Script.Serialization;

var jsonSerialiser = new JavaScriptSerializer();
var json = jsonSerialiser.Serialize(aList);
Jodrell
quelle
1
ah ok, es serialisiert AUCH Listen von Objekten und nicht nur Objekte selbst. Vielen Dank.
Frenchie
mag keine zyklischen Beziehungen, aber das ist hier kein Problem
Jodrell
13
Beachten Sie, dass dieser Namespace in System.Web.Extensions geschickt versteckt ist. Sobald Sie dies als Referenz hinzufügen, funktioniert die Lösung hervorragend!
Acht-Bit-Guru
1
Ich sehe Ihre bearbeitete Antwort und wünschte wirklich, ich hätte ein aktualisiertes Beispiel.
Dylan Brams
1
@ IamNumber5 bereits in der anderen Antwort angegeben. Ich habe meine Antwort trotzdem erweitert.
Jodrell
111

Sie können auch Json.NET verwenden. Laden Sie es einfach unter http://james.newtonking.com/pages/json-net.aspx herunter , extrahieren Sie die komprimierte Datei und fügen Sie sie als Referenz hinzu.

Dann serialisieren Sie einfach die Liste (oder ein beliebiges Objekt) wie folgt:

using Newtonsoft.Json;

string json = JsonConvert.SerializeObject(listTop10);

Update: Sie können es auch über den NuGet Package Manager (Tools -> NuGet Package Manager -> Package Manager Console) zu Ihrem Projekt hinzufügen:

PM> Install-Package Newtonsoft.Json

Dokumentation: Serialisierung von Sammlungen

Brent Barbata
quelle
11

Es gibt zwei gängige Methoden, um dies mit integrierten JSON-Serialisierern zu tun:

  1. JavaScriptSerializer

    var serializer = new JavaScriptSerializer();
    return serializer.Serialize(TheList);
  2. DataContractJsonSerializer

    var serializer = new DataContractJsonSerializer(TheList.GetType());
    using (var stream = new MemoryStream())
    {
        serializer.WriteObject(stream, TheList);
        using (var sr = new StreamReader(stream))
        {
            return sr.ReadToEnd();
        }
    }

    Beachten Sie, dass für diese Option die Definition eines Datenvertrags für Ihre Klasse erforderlich ist:

    [DataContract]
    public class MyObjectInJson
    {
       [DataMember]
       public long ObjectID {get;set;}
       [DataMember]
       public string ObjectInJson {get;set;}
    }
Joulukuusi
quelle
5
public static string JSONSerialize<T>(T obj)
        {
            string retVal = String.Empty;
            using (MemoryStream ms = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
                serializer.WriteObject(ms, obj);
                var byteArray = ms.ToArray();
                retVal = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
            }
            return retVal;
        }
samsanthosh2008
quelle
4

.NET unterstützt bereits seit Version 3.5 die grundlegende Json-Serialisierung über den System.Runtime.Serialization.Json-Namespace und die DataContractJsonSerializer- Klasse. Wie der Name schon sagt, berücksichtigt DataContractJsonSerializer alle Datenanmerkungen, die Sie Ihren Objekten hinzufügen, um die endgültige Json-Ausgabe zu erstellen.

Dies kann nützlich sein, wenn Sie bereits kommentierte Datenklassen haben, mit denen Sie Json in einen Stream serialisieren möchten, wie unter Gewusst wie: Serialisieren und Deserialisieren von JSON-Daten beschrieben . Es gibt Einschränkungen, aber es ist gut genug und schnell genug, wenn Sie Grundbedürfnisse haben und Ihrem Projekt keine weitere Bibliothek hinzufügen möchten.

Der folgende Code serialisiert eine Liste des Konsolenausgabestreams. Wie Sie sehen, ist es ein etwas ausführlicher als Json.NET und nicht typsicher (dh keine Generika).

        var list = new List<string> {"a", "b", "c", "d"};

        using(var output = Console.OpenStandardOutput())                
        {                
            var writer = new DataContractJsonSerializer(typeof (List<string>));
            writer.WriteObject(output,list);
        }

Auf der anderen Seite bietet Json.NET eine viel bessere Kontrolle darüber, wie Sie Json generieren. Dies ist SEHR praktisch, wenn Sie .NET-Klassen Namen von Javascript-freundlichen Namen zuordnen, Daten json formatieren usw. müssen.

Eine weitere Option ist ServiceStack.Text , Teil des ServicStack ... -Stacks , der eine Reihe sehr schneller Serialisierer für Json, JSV und CSV bereitstellt.

Panagiotis Kanavos
quelle
0

Aufbauend auf einer Antwort aus einem anderen Beitrag. Ich habe mir eine allgemeinere Methode zum Erstellen einer Liste ausgedacht, bei der der dynamische Abruf mit Json.NET Version 12.x verwendet wird

using Newtonsoft.Json;

static class JsonObj
{
    /// <summary>
    /// Deserializes a json file into an object list
    /// Author: Joseph Poirier 2/26/2019
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="fileName"></param>
    /// <returns></returns>
    public static List<T> DeSerializeObject<T>(string fileName)
    {
        List<T> objectOut = new List<T>();

        if (string.IsNullOrEmpty(fileName)) { return objectOut; }

        try
        {
            // reading in full file as text
            string ss = File.ReadAllText(fileName);

            // went with <dynamic> over <T> or <List<T>> to avoid error..
            //  unexpected character at line 1 column 2
            var output = JsonConvert.DeserializeObject<dynamic>(ss);

            foreach (var Record in output)
            {
                foreach (T data in Record)
                {
                    objectOut.Add(data);
                }
            }
        }
        catch (Exception ex)
        {
            //Log exception here
            Console.Write(ex.Message);
        }

        return objectOut;
    }
}

Aufruf zur Bearbeitung

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = JsonObj.DeSerializeObject<string>(fname);
}

oder dieser Aufruf zu verarbeiten

{
        string fname = "../../Names.json"; // <- your json file path

        // for alternate types replace string with custom class below
        List<string> jsonFile = new List<string>();
        jsonFile.AddRange(JsonObj.DeSerializeObject<string>(fname));
}
Joseph Poirier
quelle