Laden...

Null-Items nach Deserialisierung mit SerializationBinder und ISerializable

Erstellt von JunkyXL vor 9 Jahren Letzter Beitrag vor 9 Jahren 1.962 Views
JunkyXL Themenstarter:in
1.665 Beiträge seit 2006
vor 9 Jahren
Null-Items nach Deserialisierung mit SerializationBinder und ISerializable

Hallo zusammen,

ich habe nach langer Zeit endlich wieder was, worauf ich im Netz nichts finden konnte.

Ich habe ein Objekt mit dem BinaryFormatter serialisiert.
Nun möchte ich dieses Objekt in ein anderes Objekt deserialisieren (migrieren).
Das ist mit dem SerializationBinder schonmal kein Problem, wenn die Properties der Objekte übereinstimmen.
Wenn die Properties jedoch abweichen, wird da ISerializable auf dem neuen Objekt nötig, um die Properties entsprechend zu übernehmen.

Jetzt zum Problem: Wenn ich ISerializable implementiere, kommt am Ende eine Null-Referenz anstelle des neuen Objekts raus. Wenn ich das Interface weglasse, funktioniert alles - bis auf die Properties, die nicht gefüllt sind, weil sie sich im Namen vom alten Objekt unterscheiden.

Deserialisung

public Car Deserialize(Stream stream)
{
    stream.Position = 0;

    var f = new BinaryFormatter();
    f.Binder = new VehicleToCarBinder();
    return (Car)f.Deserialize(stream);
}

VehicleToCarBinder

public class VehicleToCarBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        if (typeName == typeof(Vehicle).FullName)
            return typeof(Car);

        if (typeName == typeof(List<Namespace1.Wheel>).FullName)
            return typeof(List<Namespace2.Wheel>);

        if (typeName == typeof(Namespace1.Wheel).FullName)
            return typeof(Namespace2.Wheel);

        return null;
    }
}

Betroffenes (neues) Objekt

namespace Namespace2
{
    [Serializable]
    public class Wheel// : ISerializable // <-- Interface auskommentieren: Unit-Test funktioniert (logischerweise ohne Property-Werte)
    {
        public Wheel()
        {
        }

        protected Wheel(SerializationInfo info, StreamingContext context)
        {
            Inches = (int)info.GetValue("<Size>k__BackingField", typeof(int));
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("<Size>k__BackingField", Inches);
        }

        public int Inches { get; set; }
        public string Type { get; set; }
    }
}

Der Test

[TestMethod]
public void SerializeVehicle()
{
    var vehicle = new Vehicle();
    vehicle.Wheels.Add(new Wheel { Size = 15, Type = "Soft" });
    vehicle.Wheels.Add(new Wheel { Size = 15, Type = "Hard" });

    var serializer = new VehicleSerializer();
    var stream = serializer.Serialize(vehicle);

    var car = serializer.Deserialize(stream);

    Assert.IsNotNull(car.Wheels[0]);
    Assert.IsNotNull(car.Wheels[1]);

    Assert.AreEqual(vehicle.Wheels[0].Type, car.Wheels[0].Type);

    // Die letzten beiden Tests sollten am Ende auch funktionieren

    //Assert.AreEqual(vehicle.Wheels[0].Size, car.Wheels[0].Inches);
    //Assert.AreEqual(vehicle.Wheels[1].Size, car.Wheels[1].Inches);
}

Anbei ist das Ganze als lauffähige Solution angehängt.

Ich hoffe, jemand stand schonmal vor dieser Problematik.

Danke euch