Using C# xmlserializer on derived classes while controlling the generated XML element

折月煮酒 提交于 2020-01-04 09:09:11

问题


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 xmlserializer 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


回答1:


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




回答2:


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.



来源:https://stackoverflow.com/questions/4285242/using-c-sharp-xmlserializer-on-derived-classes-while-controlling-the-generated-x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!