如何强制.NET的XmlSerializer将xsi:type =“FooClass”添加到类型为的成员/节点FooClass
?如何强制使用xsi:type属性?
的方案是一种目前发布的应用程序,其中在第1节:
- FooClass继承FooBaseClass
- FooPropertyA是FooBaseClass
- FooPropertyB是FooClass
- FooBaseClass装饰有[ XmlInclude(typeof(FooClass))]
- BazClass has FooBaseClass类型的成员Foo
- 所有成套的Baz。美孚是一个FooClass实例
- Baz.Foo的所有用途指望FooPropertyB(等等FooClass实例VS FooBaseClass)
的目标是:在保持删除FooBaseClass完全推FooBaseClass成员成FooClass,反向序列化兼容性
问题:然后我失去了Baz.Foo序列化的xsi:type =“FooClass”属性。
换句话说
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; }
}
需求XmlSerializer.Serialize输出是
<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,并将其分配给父Baz实例的Foo属性。因此,任何检查Baz.Foo是FooClass还是直接强制转换的代码都会失败。
的xsi:type属性在其中是
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; }
}
我认为简单的答案是,你不能在第1节的代码自动放置 - 至少在没有实现我(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
{
}
工作就像一个魅力!第二组眼睛的值... :-) – 2009-12-22 18:20:40
当类型位于另一个名称空间时不起作用。 – 2014-05-27 14:05:21
此声明中的命名空间用于'type'属性,而不是类型本身。如果你需要一个类型与元素本身不同的名称空间,那么我认为你可以通过手动注入一个'xmlns'属性(通过使用一个虚拟的'[XmlAttribute]'属性)来以类似的方式破解它。 ,然后在typename中引用它。 – 2014-05-27 16:45:35