2014-04-29 3 views
10

Hoffentlich ist dies eine einfache Lösung, die ich übersehen habe. Ich habe ein Objekt in einem Event-Handler übergeben, die ich dieses Objekt mit JSON.NET serialisieren möchten, etwa so:JSON.NET Serialisierung für ein Objekt mit einem Member vom Typ Stream?

public void OnEvent(IEventObject foo) 
{ 
    // Serialize foo to string/disk here? 
    var data = JsonConvert.SerializeObject(foo, Formatting.Indented); 
} 

Es scheint, dass eine oder mehrere der foo-Mitglieder Streams sind. Ich erkenne bereits, dass Streams nicht serialisierbar sind, da sie eine Abstraktion über Daten und nicht die Daten selbst sind. Das macht Sinn.

Ich weiß nicht, wie diese Aufgabe ohnehin entweder serialisiert:

  • a) die Ströme in Daten umwandeln und Serialisierung, dass
  • b) die Ströme zu ignorieren und serialisiert werden die übrigen Mitglieder

Eine große Einschränkung ist, dass ich nicht auf IEventObject oder seine Implementierungen zugreifen kann, so kann ich keine dieser Objekte mit Attributflags markieren.

Die einzige Lösung, die ich gefunden habe, ist dieses Objekt in meine eigene Klasse einzupacken, es entsprechend zu markieren und zu serialisieren. Später würde ich wieder in meine eigene Klasse deserialisieren und sie in das ursprüngliche Objekt konvertieren. Ich mag diesen Ansatz nicht, da er einen zusätzlichen Objekt- und Konvertierungsschritt beinhaltet und diesen nach Möglichkeit vermeiden möchte.

+1

Ich sah mich dem gleichen Problem gegenüber und hatte keine andere Wahl, als dieses in ein Objekt von mir einzubauen, das vollständig serialisierbar ist. Wenn es eine andere Option gibt würde ich mich freuen, sie auch zu hören :-) –

+0

@Bartdude können Sie meine Antwort überprüfen. –

+0

@TimS. Leider musste ich in diesem Fall das Wrapper-Objekt implementieren, da ich keinen lokalen Zugriff auf konkrete Typen zur Deserialisierung habe. Ansonsten ist die akzeptierte Antwort eine großartige Lösung für dieses Problem. – jmsb

Antwort

13

Standardmäßig versucht Json.NET, die Eigenschaften des Streams zu serialisieren, was nicht sehr nützlich ist. Sie können das Verhalten ändern, indem Sie erstellen. Hier ist ein Beispiel, das vollständig alle Stream s ignoriert:

public class IgnoreStreamsResolver : DefaultContractResolver 
{ 
    protected override JsonProperty CreateProperty(
     MemberInfo member, 
     MemberSerialization memberSerialization 
    ) 
    { 
     JsonProperty property = base.CreateProperty(member, memberSerialization); 
     if (typeof(Stream).IsAssignableFrom(property.PropertyType)) 
     { 
      property.Ignored = true; 
     } 
     return property; 
    } 
} 

verwenden Sie es wie:

var bytes = new byte[] { 1, 2, 3 }; 
var eo = new EventObject { OtherValue = 2, MyStream = new MemoryStream(bytes) }; 
var s = JsonConvert.SerializeObject(eo, 
    new JsonSerializerSettings { ContractResolver = new IgnoreStreamsResolver() }); 
// {"OtherValue":2} 

Durch Modifikation anderer Eigenschaften des JsonProperty, können Sie andere Änderungen vornehmen. Die eine, die aussieht, als wäre sie für Sie am nützlichsten, ist Converter, mit der Sie Ihre eigene Klasse definieren können, um zu definieren, wie die Stream serialisiert wird (z. B. in eine byte[] konvertieren und diese als base64 serialisieren).

All dies erfolgt ohne Änderungen an der Schnittstelle oder der implementierenden Klasse.

+0

Genau das habe ich gesucht. Ich schaue nach der Implementierung und dem Testen selbst zurück. Vielen Dank. – jmsb

Verwandte Themen