Unten ist ein vereinfachtes Beispiel für das, was ich erreichen möchte.DataContractJsonSerializer; ISerializable GetObjectData mit .NET aufgerufen aber nicht mit Mono
Ich habe eine Klasse DoNotSerializeMe, die Teil einer externen Bibliothek ist und nicht serialisiert werden kann.
Ich habe auch eine Klasse SerializeMe, die ein Mitglied des Typs DoNotSerializeMe hat. Ich kann diese Klasse dazu bringen, ISerializable zu implementieren und das Problem zu umgehen, dass DoNotSerializeMe nicht serialisierbar ist, indem man Daten zieht und den Konstruktor aufruft.
using System.Runtime.Serialization;
using System.Security.Permissions;
namespace CustomJsonSerialization
{
[System.Serializable]
public class SerializeMe : ISerializable
{
public DoNotSerializeMe SerializeMeThroughISerializable;
public SerializeMe(string mystring)
{
SerializeMeThroughISerializable = new DoNotSerializeMe(mystring);
}
protected SerializeMe(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine(" In SerializeMe constructor (ISerializable)");
SerializeMeThroughISerializable = new DoNotSerializeMe(info.GetString("SerializeMeThroughISerializable"));
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
System.Console.WriteLine(" In SerializeMe.GetObjectData()");
info.AddValue("SerializeMeThroughISerializable",
"(deserialized through getObjectData " +
SerializeMeThroughISerializable.WhyAmIHere + ")");
}
}
}
Im Folgenden finden Sie ein kurzes Programm, das das Objekt serialisiert und deserialisiert:
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace CustomJsonSerialization
{
public class Program
{
public static void Main(string[] args)
{
SerializeMe serializeme = new SerializeMe("initial");
Console.WriteLine("I created it: {0}", serializeme.SerializeMeThroughISerializable.WhyAmIHere);
Console.WriteLine();
MemoryStream memstream = new MemoryStream();
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(SerializeMe));
serializer.WriteObject(memstream, serializeme);
Console.WriteLine("I serialized it: {0}", serializeme.SerializeMeThroughISerializable.WhyAmIHere);
Console.WriteLine();
Console.WriteLine("Json:");
Console.WriteLine(Encoding.ASCII.GetString(memstream.ToArray()));
Console.WriteLine();
memstream.Seek(0, SeekOrigin.Begin);
SerializeMe anotherSerializeMe = (SerializeMe)serializer.ReadObject(memstream);
Console.WriteLine("I deserialized it: {0}", anotherSerializeMe.SerializeMeThroughISerializable.WhyAmIHere);
}
}
}
Wenn durch .NET (4.5) ausgeführt wird, erhalte ich folgendes:
In DoNotSerializeMe constructor.
I created it: (constructed with initial)
In SerializeMe.GetObjectData()
I serialized it: (constructed with initial)
Json:
{"SerializeMeThroughISerializable":"(deserialized through getObjectData (constructed with initial))"}
In SerializeMe constructor (ISerializable)
In DoNotSerializeMe constructor.
I deserialized it: (constructed with (deserialized through getObjectData (constructed with initial)))
Der Serializer genannt die ISerializable-Konstruktion und die GetObjectData beim Serialisieren/Deserialisieren (wie erwartet). Ich serialisiert oder deserialisiert das DoNotSerializeMe-Objekt nicht direkt.
Allerdings, wenn Sie die gleiche Build über Mono (versuchte 3.10.0 und 4.0.2) ausführen, bekomme ich Folgendes: In DoNotSerializeMe Konstruktor. ich es erstellt: (mit anfänglichem gebaut)
I serialized it: (constructed with initial)
Json:
{"SerializeMeThroughISerializable":{"WhyAmIHere":"(constructed with initial)"}}
I deserialized it: (constructed with initial)
Offensichtlich wenn DoNotSerializeMe wirklich nicht serialisierbar waren, würde dies zu einem Fehler führen.
Gibt es eine elegante Möglichkeit, dies ohne Json.NET zu umgehen? Ich bin mir nicht sicher, warum mono verhält sich nicht so wie .NET.
, welche Version von Mono verwenden Sie? – knocte
@knocte, habe ich 3.10.0 und 4.0.2 versucht. – Jaws
Ich empfehle Ihnen, mit einer Version zu testen, die so modern ist wie die von Ubuntu 16.04 beinhaltet, zumindest (was ich denke, es ist 4.2.3) – knocte