code it

Martins Tech Blog

In die JSON-Serialisierung eingreifen

Der Anwendungsfall

In einer Seite sollen Diagramme angezeigt werden. Für die Darstellung habe ich mich für flot entschieden. Dabei handelt es sich um eine JavaScript-Bibliothek, die in einem Platzhalter mit Hilfe von Canvas-Elementen Charts in diversen Formaten zeichnen kann. 

Im ersten Beispiel soll ein Tortendiagramm erzeugt werden. 

Die Datenstruktur ist dabei recht simpel. Es handelt sich um ein Array von Objekten mit jeweils einem Label und einem Zahlenwert für die Daten.

var pieData = [{ label: "geschieden", data: 5 }, { label: "verheiratet", data: 25 }, { label: "ledig", data: 30 }];
$.plot($("#myChart"), pieData, {
    series: {
        pie: {
            show: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

Im zweiten Beispiel soll ein Liniendiagramm erzeugt werden, das Werte mehrerer Serien über einen Zeitraum darstellen kann.

Die Datenstruktur ist ähnlich wie die des Tortendiagramms. Nur nun enthält data nicht mehr einen einzelnen Wert, sondern ein Array von x-y-Werten. das Beispiel beinhaltet die Daten vom 01.11. bis 03.11.2012. Die x-Achse ist auf den Zeitraum 31.10. bis 04.11. arretiert, damit der erste Datenwert nicht direkt am Rand des Charts liegt.

var lineData = [
    { label: "aktive Kunden", data: [[1351724400000, 213], [1351810800000, 215], [1351897200000, 217]] },
    { label: "Support Tickets", data: [[1351724400000, 100], [1351810800000, 80], [1351897200000, 70]] }
];
$.plot($("#myChart"), lineData, {
    xaxis: {
        mode: "time",
        min: new Date(2012, 09, 31).getTime(),
        max: new Date(2012, 10, 4).getTime(),
    },
    yaxis: {
        tickDecimals: 0,
        min: 0,
        max: 300
    },
    series: {
        lines: { show: true },
        points: {
            radius: 3,
            show: true,
            fill: true
        }
    },
    grid: {
        hoverable: true
    },
    legend: {
        labelBoxBorderColor: "none"
    }
});

So weit so gut. Mehr...

back to basics: Generische XML-Serialisierung

Im heutigen btb-Post soll es um das Thema XML-Serialisierung gehen. Häufig sieht man im Alltag oder in Foren die Frage, wie ein Objekt in einen String serialisiert werden kann - z.B. um diese Daten dann in einem Datenspeicher abzulegen.

Im Grunde ist der Vorgang recht einfach: Man erzeugt einen XMLSerializer des zu (de-)serialisierenden Objekts und ruft dessen Serialize- bzw. Deserialize-Methode auf. Wenn man sich noch nie mit der Problemstellung beschäftigt hat, stellt sich dann aber die Frage, welche Parameter man der Methode übergibt, da hier String als Parametertyp nicht existiert. Verwendet man diese Methode häufiger, so ist es zudem noch nervig, am Ende der Deserialisierung den Cast zum Ziel-Typ zu machen.

Um die Sache zu vereinfachen kann man sich mit Hilfe von Generics recht einfach zwei Methoden schreiben, die diesen Task übernehmen.

static string SerializeObject<T>(T objectToSerialize)
{
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  using (StringWriter writer = new StringWriter())
  {
      serializer.Serialize(writer, objectToSerialize);
      return writer.ToString();
  }
}

static T DeserializeObject<T>(string serializedData)
{
  XmlSerializer serializer = new XmlSerializer(typeof(T));
  using (StringReader reader = new StringReader(serializedData))
  {
      return (T)serializer.Deserialize(reader);
  }
}

Der Aufruf ist dann recht einfach:

Employee employee1 = new Employee { Name = "André Meyer" };
string serializedEmployee = SerializeObject(employee1);
Employee employee2 = DeserializeObject<Employee>(serializedEmployee);

Einen kleinen interessanten Nebeneffekt hat diese Art noch, wenn es auch nicht die beste Art ist, dieses Ziel zu erreichen: Durch die Serialisierung und Deserialisierung ist eine 1:1-Kopie des ursprünglichen Objekts entstanden.