Wie kann ich die Verwendung eines xsi: type-Attributs erzwingen?

Wie kann ich den XmlSerializer von .NET zwingen, einexsi: type = "FooClass" an ein Mitglied / einen Knoten vom TypFooClass?

Das Szenario ist eine aktuell veröffentlichte App, in der in Version 1:

FooClass erbt FooBaseClassFooPropertyA ist in der FooBaseClassFooPropertyB ist bei FooClassFooBaseClass ist dekoriert mit [XmlInclude (typeof (FooClass))]BazClass hat das Mitglied Foo vom Typ FooBaseClassAlle Sätze von Baz.Foo beziehen sich auf eine FooClass-InstanzAlle Verwendungen von Baz.Foo erwarten FooPropertyB (und somit eine FooClass-Instanz gegenüber FooBaseClass)

Das Ziel: FooBaseClass vollständig entfernen und die Mitglieder von FooBaseClass nach oben in FooClass schieben,bei gleichzeitiger Aufrechterhaltung der Abwärtsserialisierungskompatibilität

Das Problem: Dann verliere ich das xsi: type = "FooClass" -Attribut in der Baz.Foo-Serialisierung.

Mit anderen Worten die XmlSerializer.Serialize-Ausgabe von

public class BazClass
{
    public BazClass()
    {
        Foo = new FooClass { A = 5, B = "Hello" };
    }
    public FooClass Foo { get; set; }
}

public class FooClass
{
    public int FooPropertyA { get; set; }
    public string FooPropertyB { get; set; }
}

muss sein

<Baz>
    <Foo xsi:type="FooClass">
        <FooPropertyA>Hello</FooPropertyA>
        <FooPropertyB>5</FooPropertyB>
    </Foo>
</Baz>

Das Entfernen von FooBasClass ist einfach, aber dann platziert XmlSerializer nicht mehr xsi: type = "FooClass" auf Baz / Foo. Daher instanziiert v.1 XmlSerializer.Deserialize eine FooBaseClass-Instanz, ohne FooPropertyB festzulegen, und weist sie der Foo-Eigenschaft des übergeordneten Elements zu Baz-Instanz. Daher schlägt jeder Code fehl, der prüft, ob Baz.Foo FooClass ist oder direkt umgewandelt wird.

Das xsi: type-Attribut wurde automatisch in den v.1-Code eingefügt

public class BazClass
{
    public BazClass()
    {
        Foo = new FooClass { A = 5, B = "Hello" };
    }
    public FooBaseClass Foo { get; set; }
}

public class FooClass : FooBaseClass
{
    public string FooPropertyB { get; set; }
}

[XmlInclude(typeof(FooClass))]    
public class FooBaseClass
{
    public int FooPropertyA { get; set; }
}

Ich denke, die kurze Antwort lautet, dass dies nicht möglich ist - zumindest nicht, ohne I (Xml) Serializable zu implementieren oder benutzerdefinierten Serialisierungscode zu schreiben. Ich bin jedoch offen für gute Vorschläge. Inzwischen habe ich eineProblemumgehung hack unten und hoffe auf etwas eleganteres, oder das erlaubt mir zumindest irgendwie, FooBaseClass komplett zu entfernen.

BazClass
{
    [XmlElement("Foo")]
    public FooBaseClass XmlFoo { get { return Foo; } set { Foo = (StartPicture)value; } }

    [XmlIgnore]
    public FooClass Foo { get; set; }
}    

FooClass : FooBaseClass
{
    public int FooPropertyB { get; set; }
    public string FooPropertyA { get; set; }
}

[XmlInclude("FooClass")]
FooBaseClass
{
}

Antworten auf die Frage(3)

Ihre Antwort auf die Frage