Reputation: 1380
Bear with me while I try to explain (over-explain?) my question. I have two objects like this:
[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; }
}
And then serialize an object to XML like this:
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();
This fails with the following exception:
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.
So changing var xs = new XmlSerializer(typeof(Professional)); will solve this particular problem. So will adding an XmlInclude attribute on Person declaring it's known types. However, what if I am not responsible for the serialization code and worse yet, what if I cannot modify the base type? Is there anyway to overcome this? I was hoping IXmlSerializable would take care of this, but it doesn't, apparently...
As a bit of context, I am asking this because of issues with serializing custom SoapHeader objects in a SoapExtension object with WSE3 library (don't ask why I'm using that). If there's no way around this, then how on earth does anyone ever use System.Web.Services.Protocols.SoapMessage.Headers.Add(SoapHeader)?
Upvotes: 1
Views: 1266
Reputation: 49435
Can you use the XmlSerializer(Type type, Type[] extraTypes)
constructor instead of the one listed above? You should be able to pass in known types to the XmlSerializer in this way.
Edit: If you are "not responsible for the serialization code" then you probably can't change the constructor. If you can't modify the base class or the serializer object, I'm not sure if there is a way to let the serializer know about the Professional
class.
Upvotes: 2