Using C# xmlserializer on derived classes while controlling the generated XML element
I've got a C# structure of classes with an abstract base class and various classes derived from this abstract class.
[System.Xml.Serialization.XmlInclude(typeof(B))]
public abstract class A {
...
}
[Serializable]
[XmlType("typename")]
public class B : A {
...
}
Furthermore, I'm using an instance of class B within another class C as a field with its abstract type like this:
public class C {
...
public A myItem { get; set; } //A is actually of type B
...
}
Now, when I serialize my class C via the standard xmlserializer, I get a XML structure like this:
<C>
<myItem p2:type="typename" xmlns:p2="...">
... //Fields as elements and stuff
</myItem>
</C>
But thats not what I need because I send those serialized C objects to a REST Webservice (which has no valid schema yet). What I actually need is something like this:
<C>
<typename>
... //Fields as elements and stuff
</typename>
</C>
But as you can see above, the x开发者_JAVA技巧mlserializer seems to prefer the instance field name over the type name set via XmlType. Also, obviously I can't just use XmlElement("typename") for my field in C, because I don't know which concrete implementation of my abstract class A the field will contain.
Has anyone ever had a similar problem and could provide me with a solution to this? Or do i really need to implement IXmlSerializable in my class A and thus within all of my concrete A-derived classes to get this working?
EDIT: Just found out while reading some articles that IXmlSerializable doesn't let me control the wrapper element, so do I actually need to implement the Interface in class C with some sort of switch() on the type of the myItem member?
Thanks for your help!
Best regards, flo
Okay, seems I have found the solution, at least for serialization, don't know yet if this also works for deserialization. The key is a special constructor for the XMLElement attribute, which allows to specify the key to use if a abstract type is used:
http://msdn.microsoft.com/en-us/library/cz6bdh5z.aspx
Maybe this is also helpful to someone else.
Best, flo
For deserialization you will need to provide the XmlSerializer with all the types that it MAY encounter in all the abstract typed properties.
The XmlSerializer has a specific constructor in which you can feed it a collection of Types.
精彩评论