为什么人们总是说“你永远无法反序列化”。
这绝对是 FALSE。
public class BaseClass {
public string Name {get;set;}
}
[XmlRoot("BaseClass")]
public class ChildClass : BaseClass {
public int Value {get;set;}
}
[XmlRoot("BaseClass")]
public class FlatClass
{
public string Name {get;set;}
public int Value {get;set;}
}
XmlSerializer ser1 = new XmlSerializer(typeof(BaseClass));
XmlSerializer ser2 = new XmlSerializer(typeof(ChildClass));
XmlSerializer ser3 = new XmlSerializer(typeof(FlatClass));
ser1.Serialize(File.Open("ser1.xml", FileMode.Create), new BaseClass(){Name="Base"});
ser2.Serialize(File.Open("ser2.xml", FileMode.Create), new ChildClass(){Name="Child",Value = 1});
ser1.Deserialize(File.OpenRead("ser2.xml"));
ser2.Deserialize(File.OpenRead("ser1.xml"));
ser3.Deserialize(File.OpenRead("ser2.xml"));
轰隆隆。工作得很好!!!!
序列化在这三个方面都完美无缺。生成的对象在任一侧可能都不是 100%,但它确实会反序列化。
Ser1 在反序列化 ser2.xml 时忽略 Value 元素
Ser2 在反序列化 ser1.xml 时跳过 Value 属性
唯一打破这种模式的是:
ser1.Serailize(File.Open("ser3.xml", FileMode.Create), new ChildClass(){Name = "Child2", Value = 2});
XmlSerialize ser3 = new XmlSerializer(typeof(FlatClass));
ser3.Deserialize(File.OpenRead("ser3.xml"));
最后一次中断,因为 BaseClass 的序列化程序遵循在元素上包含 xsi:type="ChildClass" 属性的架构标准(尽管这是一个有价值且 99% 的时间标准)。 Ser3 无法处理该类型,因为它与该类型无关,特别是如果 FlatClass 存在于跨 WAN 或 LAN 线路的另一个程序集中。
就像 Honey-badger 一样,XmlSerailizer 不关心元素或值,只要它可以找到它们并且架构中的任何内容都不会破坏该过程。 XSI:TYPE 属性破坏了架构。
例如,当使用 WCF 或其他基于 XML 通信的系统时,如果服务有一个名为 FlatClass 的类,它不会反序列化包含 xsi:type="" 属性的 ChildClass。但是,如果您不使用 BaseClass 的序列化程序,它将反序列化完全相同的 XML,而无需该 xsi:type 属性。
Q.E.D.
不包含 xsi:type 属性通常是有益的、必要的和可取的。
这么说有没有办法为 BaseClass 类型创建一个 XmlSerializer 并告诉它在序列化子类型时不要包含 xsi:type 属性?
谢谢
Jaeden "Sifo Dyas" al'Raec 毁灭者