5 Stimmen

Serialisierung in einem menschenlesbaren Textformat

Gibt es eine Möglichkeit in .NET 2.0 (C#) zu serialisieren Objekt wie Sie mit XmlSerializer in einem einfachen / anpassbare menschenlesbare Format, das zum Beispiel aussieht wie PXLS oder JSON? Auch ich weiß, dass XML für den Menschen lesbar ist, ich bin auf der Suche nach etwas mit weniger lästigen Redundanz, etwas, das Sie auf der Konsole als Ergebnis für den Benutzer ausgeben können.

7voto

ullmark Punkte 2479

Zum Serialisieren in JSON in .NET gehen Sie wie folgt vor:

public static string ToJson(IEnumerable collection)
        {
            DataContractJsonSerializer ser = new DataContractJsonSerializer(collection.GetType());
            string json;
            using (MemoryStream m = new MemoryStream())
            {
                XmlDictionaryWriter writer = JsonReaderWriterFactory.CreateJsonWriter(m);
                ser.WriteObject(m, collection);
                writer.Flush();

                json = Encoding.Default.GetString(m.ToArray());
            }
            return json;
        }

Das Element "Collections" muss das Attribut "DataContract" haben, und jedes Mitglied, das in das JSON serialisiert werden soll, muss das Attribut "DataMember" haben.

Es ist möglich, dass dies nur für .NET 3.5 funktioniert. Aber es gibt auch eine ebenso einfache Version für 2.0...

4voto

Zax Punkte 306

Eine ausführliche Dokumentation habe ich hier gefunden:

http://pietschsoft.com/post/2008/02/NET-35-JSON-Serialization-using-the-DataContractJsonSerializer.aspx

mit dieser nützlichen Klasse (Unterstützung von Generika)

using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

public class JSONHelper
{
  public static string Serialize<T>(T obj)
  {
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
      MemoryStream ms = new MemoryStream();
      serializer.WriteObject(ms, obj);
      string retVal = Encoding.Default.GetString(ms.ToArray());
      ms.Dispose();
      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();
      ms.Dispose();
      return obj;
  }
}

2voto

Joel Coehoorn Punkte 377088

Die eingebauten Serialisierungsoptionen für .Net sind Xml, Xml-Soap und Binary. Da Sie Xml ausgeschlossen haben und Binary definitiv nicht für Menschen lesbar ist, müssen Sie Ihre eigene Serialisierung entwickeln.

Wenn Sie Ihre eigene Rolle drehen, haben Sie mehrere Möglichkeiten:

  • Fügen Sie der Klasse Utility- oder Extention-Methoden hinzu, wie von AviewAnew vorgeschlagen
  • Erweitern Sie System.Runtime.Serialization.Formatter / Implementieren Sie System.Runtime.Serialization.IFormatter
  • Finden Sie online über Google ein allgemeines Bauteil, das Ihren Anforderungen entspricht.

Beachten Sie, dass der 2. Punkt für Ihre spezifische Klasse spezialisiert werden kann (er muss nicht jede beliebige Klasse behandeln können, wenn Sie das nicht wollen) und die beiden letzten Punkte sich nicht gegenseitig ausschließen.

Ich habe für eine .Net JSON-Formatierer in der Vergangenheit gesucht, und es gibt definitiv mehrere Optionen da draußen. Allerdings endete ich gehen eine andere Richtung, die Zeit. Ich fühlte mich einfach nicht sehr zuversichtlich in einem von ihnen. Vielleicht kann jemand anderes eine genauere Empfehlung aussprechen. JSON wird so wichtig, dass Microsoft hoffentlich bald eine "native" Unterstützung dafür in das Framework aufnehmen wird.

1voto

Makeman Punkte 634

https://stackoverflow.com/a/38538454/6627992

Sie können folgende Standardmethode verwenden, um formatiertes Json zu erhalten

JsonReaderWriterFactory.CreateJsonWriter(Stream stream, Encoding encoding, bool ownsStream, bool indent, string indentChars)

Nur einstellen "einrücken==true"

Versuchen Sie etwas wie dies

    public readonly DataContractJsonSerializerSettings Settings = 
            new DataContractJsonSerializerSettings
            { UseSimpleDictionaryFormat = true };

    public void Keep<TValue>(TValue item, string path)
    {
        try
        {
            using (var stream = File.Open(path, FileMode.Create))
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture;
                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                        stream, Encoding.UTF8, true, true, "  "))
                    {
                        var serializer = new DataContractJsonSerializer(type, Settings);
                        serializer.WriteObject(writer, item);
                        writer.Flush();
                    }
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                }
                finally
                {
                    Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.ToString());
        }
    }

Achten Sie auf die Linien

    var currentCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    ....
    Thread.CurrentThread.CurrentCulture = currentCulture;

Sie sollten Folgendes verwenden UnveränderlicheKultur um Ausnahmen bei der Deserialisierung auf Computern mit unterschiedlichen regionalen Einstellungen zu vermeiden. Zum Beispiel, ungültiges Format von doppelt ou DateTime verursachen sie manchmal.

Für die Deserialisierung

    public TValue Revive<TValue>(string path, params object[] constructorArgs)
    {
        try
        {
            using (var stream = File.OpenRead(path))
            {
                var currentCulture = Thread.CurrentThread.CurrentCulture;
                Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    var serializer = new DataContractJsonSerializer(type, Settings);
                    var item = (TValue) serializer.ReadObject(stream);
                    if (Equals(item, null)) throw new Exception();
                    return item;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                    return (TValue) Activator.CreateInstance(type, constructorArgs);
                }
                finally
                {
                    Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch
        {
            return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
        }
    }

Merci !

0voto

frenchone Punkte 1388

Wenden Sie ein xsl auf Ihre xml an, um das herauszunehmen, was Sie nicht sehen wollen?

etwas wie

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
  <xsl:template match="*">
      <xsl:value-of select="name()" /><xsl:text>
</xsl:text>
      <xsl:apply-templates select="@*"/>
<xsl:apply-templates select="*"/>
  </xsl:template>
  <xsl:template match="@*|text()|comment()|processing-instruction">
   <xsl:value-of select="name()" />:<xsl:value-of select="." /><xsl:text>
</xsl:text>
  </xsl:template>
</xsl:stylesheet>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X