如果我不能修改基类型,如何以C#多态方式将对象序列化为XML?

时间:2010-11-01 21:20:59

标签: c# xml-serialization

在我尝试解释(过度解释?)我的问题时,请耐心等待。我有两个这样的对象:

[XmlRoot("person")]
public class Person
{
    [XmlElement("name")]
    public string Name { get; set; }

    [XmlElement("ssn")]
    public string Ssn { get; set; }
}

[XmlRoot("professional")]
public class Professional : Person
{
    [XmlElement("occupation")]
    public string Occupation { get; set; }
}

然后将对象序列化为XML,如下所示:

var p = new Professional()
{
    Name = "Nick Riveria",
    Ssn = "123-12-1234",
    Occupation = "doctor"
};

var writerSettings = new XmlWriterSettings
{
    OmitXmlDeclaration = true
};

var xs = new XmlSerializer(typeof(Person));
var stringWriter = new StringWriter();
using (var xmlWriter = XmlWriter.Create(stringWriter, writerSettings))
{
    xs.Serialize(xmlWriter, p);
}

return stringWriter.ToString();

此操作失败,但出现以下异常:

System.InvalidOperationException: There was an error generating the XML document. ---> System.InvalidOperationException: The type Professional may not be used in this context. To use Professional as a parameter, return type, or member of a class or struct, the parameter, return type, or member must be declared as type Professional (it cannot be object). Objects of type Professional may not be used in un-typed collections, such as ArrayLists.

所以改变var xs = new XmlSerializer(typeof(Professional));将解决这个特殊问题。因此,将在Person上添加一个XmlInclude属性来声明它的已知类型。但是,如果我不对序列化代码负责,更糟糕的是,如果我不能修改基类型怎么办?无论如何要克服这个?我希望IXmlSerializable可以解决这个问题,但事实并非如此......

作为一个上下文,我问这个是因为在使用WSE3库的SoapExtension对象中序列化自定义SoapHeader对象的问题(不要问我为什么要使用它)。如果没有办法解决这个问题,那么究竟怎么会有人使用System.Web.Services.Protocols.SoapMessage.Headers.Add(SoapHeader)?

1 个答案:

答案 0 :(得分:2)

您可以使用XmlSerializer(Type type, Type[] extraTypes)构造函数而不是上面列出的构造函数吗?您应该能够以这种方式将已知类型传递给XmlSerializer。

编辑:如果您“不负责序列化代码”,那么您可能无法更改构造函数。如果您无法修改基类或序列化程序对象,我不确定是否有办法让序列化程序了解Professional类。