Как я могу заставить XmlSerializer .NET добавить xsi: type = "FooClass" члену/узлу типа FooClass
?Как я могу заставить использовать атрибут xsi: type?
Сценарий представляет собой в настоящее время выпустила приложение, где в т.1:
- FooClass наследует FooBaseClass
- FooPropertyA на FooBaseClass
- FooPropertyB на FooClass
- FooBaseClass украшен [ XmlInclude (typeof (FooClass))
- BazClass имеет член Foo типа FooBaseClass
- Все комплекты Baz. Foo являются к экземпляру FooClass
- Все Обычаи Baz.Foo ожидают FooPropertyB (и поэтому экземпляр FooClass против FooBaseClass)
Цель: Удалить FooBaseClass полностью, толкая членов FooBaseClass в очередной раз в FooClass, при сохранении обратная совместимость сериализации
проблема: Тогда я теряю XSI: тип = атрибут «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: тип = "FooClass" на Baz/Foo, и поэтому v.1 XmlSerializer.Deserialize создает экземпляр FooBaseClass, не устанавливая FooPropertyB, и присваивает его свойству Foo родительского экземпляра Baz. Таким образом, любой код, который проверяет, является ли Baz.Foo FooClass или выполняется напрямую, терпит неудачу.
XSI: атрибут типа был помещен автоматически в т.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) Сериализуемый или написание пользовательского кода сериализации. Тем не менее, я открыт для хороших предложений. Между тем, я применил обходное решение, и я надеюсь на что-то более элегантное, или это по крайней мере позволяет мне как-то полностью удалить 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
{
}
работал как шарм! значение второго набора глаз ... :-) –
Не работает, когда тип находится в другом пространстве имен. –
Пространство имен в этом объявлении предназначено для атрибута 'type', а не для самого типа. Если вам нужен тип, который находится в пространстве имен, отличном от того самого элемента, то я думаю, что вы можете взломать его аналогичным образом, вручную введя атрибут 'xmlns' (используя свойство фиктивного' [XmlAttribute] ') , а затем ссылаясь на это в имени типа. –