Как я могу принудительно использовать атрибут xsi: type?
Как я могу заставить .NET XmlSerializer добавитьXSI: тип = "FooClass" члену / узлу типаFooClass
?
Сценарий представляет собой приложение, выпущенное в настоящее время, где в v.1:
FooClass наследует FooBaseClassFooPropertyA находится на FooBaseClassFooPropertyB находится на FooClassFooBaseClass оформлен с помощью [XmlInclude (typeof (FooClass))]BazClass имеет член Foo типа FooBaseClassВсе наборы Baz.Foo относятся к экземпляру FooClassВсе виды использования Baz.Foo ожидают FooPropertyB (и, следовательно, экземпляр FooClass против FooBaseClass)Цель: полностью удалить FooBaseClass, подтолкнув членов FooBaseClass в FooClass,при сохранении обратной совместимости сериализации
Проблема: тогда я теряю атрибут xsi: type = "FooClass" при сериализации Baz.Foo.
Другими словами, вывод XmlSerializer.Serialize
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; }
}
должно быть
<Baz>
<Foo xsi:type="FooClass">
<FooPropertyA>Hello</FooPropertyA>
<FooPropertyB>5</FooPropertyB>
</Foo>
</Baz>
Удалить FooBasClass легко, но тогда XmlSerializer больше не помещает xsi: type = "FooClass" в Baz / Foo, и поэтому v.1 XmlSerializer.Deserialize создает экземпляр FooBaseClass, не устанавливая FooPropertyB, и назначает его свойству Foo родительского объекта Баз инстанс. Таким образом, любой код, который проверяет, является ли Baz.Foo FooClass или выполняет непосредственное приведение, завершается ошибкой.
Атрибут xsi: type был автоматически помещен в код v.1, который был
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; }
}
Я думаю, что короткий ответ заключается в том, что вы не можете - по крайней мере, без реализации I (Xml) Serializable или написания собственного кода сериализации. Тем не менее, я открыт для хороших предложений. Тем временем я реализовалобходной путь хак ниже, и я надеюсь на что-то более элегантное, или, по крайней мере, позволяет мне как-то полностью удалить FooBaseClass.
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
{
}