【发布时间】:2014-03-20 14:09:20
【问题描述】:
我有一个带有几个属性的基类和三个派生类。
我想序列化一个包含所有三个派生类的对象,但每个派生类都应该从基类公开一组不同的属性。
我想用 XmlAttributeOverrides 动态地做到这一点,并尝试了几种不同的方法来做到这一点,但没有真正做到这一点。
[Serializable]
public class A
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
[Serializable]
public class B : A
{
}
[Serializable]
public class C : A
{
}
[Serializable]
public class Container
{
public B B { get; set; }
public C C { get; set; }
}
class Program
{
static void Main(string[] args)
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter encodingWriter = new StreamWriter(memoryStream, Encoding.Unicode);
var xmlWriter = XmlWriter.Create(encodingWriter, new XmlWriterSettings
{
Indent = false,
OmitXmlDeclaration = true,
});
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribute = new XmlAttributes();
attribute.XmlIgnore = true;
overrides.Add(typeof(B), "Property1", attribute);
overrides.Add(typeof(C), "Property2", attribute);
var container = new Container
{
B = new B {Property1 = "B property 1", Property2 = "B property 2"},
C = new C {Property1 = "C property 1", Property2 = "C property 2"}
};
var xmlSerializer = new XmlSerializer(typeof(Container), overrides);
xmlSerializer.Serialize(xmlWriter, container);
var result = Encoding.Unicode.GetString(memoryStream.ToArray());
}
}
在上面的代码中,结果字符串将包含 A 在 B 和 C 中的所有属性,但我真的希望它只包含 B Property2 和 C Property1(因为我已经为它们设置了 XmlIgnore 属性)。
我该怎么做?
编辑:预期的 XML:
<Container xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><Property2>B property 2</Property2></B><C><Property1>C property 1</Property1></C></Container>
实际的 XML:
<Container xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><Property1>B property 1</Property1><Property2>B property 2</Property2></B><C><Property1>C property 1</Property1><Property2>C property 2</Property2></C></Container>
编辑 2:以上是可视化问题的示例,但我将详细说明为什么我们需要这样做。
我们有一个容器类(如上),其中包含不同类型的派生对象(如上)。 当我们将 Container-class 中的数据暴露给其他人时,我们希望能够仅暴露某些可在其他地方配置的字段(可能是敏感数据或其他)。
我们在 XmlAttributeOverrides 的帮助下为暴露的属性设置 XmlIgnore 属性。这适用于大多数类型的对象(没有继承),但现在我们需要以不同的方式(可配置)序列化不同的派生对象。
所以在上面的例子中,一些客户决定从 B 类中排除 Property1,从 C 类中排除 Property2,因此我希望 XML 看起来像上面那样。 但是,这不适用于上面的代码;似乎 XmlSerializer 使用基类 A 中的属性设置,而不是使用各自派生类 B 和 C 中的设置。
【问题讨论】:
-
虽然与您的问题无关,但请注意,使用
XmlSerializer时不需要[Serializable]属性。 -
我最终(由于其他原因)单独序列化所有部分(通过反射),这在解决另一个问题的同时也解决了这个问题。 @ChrisSinclair 虽然有足够的解决方案,所以我将其标记为答案。
标签: c# serialization