2

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

flo
  • 49
  • 1
  • 5

2 Answers2

2

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

flo
  • 49
  • 1
  • 5
0

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.

Anton
  • 5,323
  • 1
  • 22
  • 25
  • Thanks, but I actually thought that is already done by specifiying the XmlInclude attribute...but it even seems to work completely without this...at the price that I need to store information specific to class B within class C...But I think that's the price I have to pay for not being able to use a valid schema for that stuff... – flo Nov 26 '10 at 13:05
  • Ah yeah, I was assuming a situation close to what we deal with at work: xml deserialization of abstract properties and/or instances with unknown derived classes. For those we gather derived types using MEF and feed them to the XmlSerializer for deserialization. – Anton Nov 26 '10 at 13:10
  • I see...thats no problem for me, as I know all the types that I have to expect, I just can't alter the webservice and as the (non-existent) schema may change, there is also no big sense in doing this via the schema -> xsd.exe -> classes indirection, aside from the fact that I'm just doing this for some kind of thesis prototype, which I don't expect to be reused after I delivered my results ;-) Thanks for the pointer to MEF, though...didn't know this one, looks very promising and might come in handy sometime! – flo Nov 26 '10 at 13:19