IXmlSerializable and Inheritance

Let's say that I have two classes: a base class and a derived class. They are fairly simple classes, and basically just act like data structures (with a derived class, obviously a little more complicated).

public class BaseUserSession { // ... Various properties ... } public class DerivedUserSession : BaseUserSession { // ... Even more properties ... } 

These classes must be serialized in XML. Now you can do this simply by specifying [Serializable] on the class declarations, and the default XML serializer works well.

In reality, however, there are several classes that inherit from the base class. My goal is to be able to use the serialized XML of any of the derived classes as a base class.

I tried two methods, none of which are currently working. First, using your own XML serializer and some control attributes in the base class. The generated XML looks something like this:

 <?xml version="1.0" encoding="utf-16"?> <DerivedUserSession xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SSO="www.mywebsite.com"> <SSO:Id /> <SSO:Authenticated>false</SSO:Authenticated> <SSO:Role /> <EmailAddress /> <FullName /> <Street /> <City /> <State /> <Zip /> <DayPhone /> <EveningPhone /> <ErrorMessage /> <Birthdate>0001-01-01T00:00:00</Birthdate> <CurrentControl>0</CurrentControl> </DerivedUserSession> 

Tags that have the SSO prefix are those that are inherited from the base class. But when I try to deserialize this into a BaseUserSession object, it throws an exception: System.InvalidOperationException: <DerivedUserSession xmlns=''> was not expected.

I also tried to make the base class IXmlSerializable , and also read and write all XML manually. However, derived classes cannot write out their properties, and I really don't want to implement IXmlSerializable for each class.

Is there an easier way to do this?

= Edit =

I finally implemented a rather ugly method for this. Two classes inherit from the base, and all of them implement IXmlSerializable . Each class (including the base) writes its field values ​​(painstakingly ...) to its own XML hierarchy using reflection, and also reads those values ​​back. The first recorded values ​​always refer to the base class.

Each application also includes code that controls serialization in XML and vice versa, providing a simple interface. The session itself does nothing more than just accept serialized XML and store it under a shared key. Serialization to and from XML is handled by the application, and the common XmlRootAttribute used in all applications to bypass an InvalidOperationException .

So, when another application tries to deserialize the XML that was originally created in another application, it manages to read the general values ​​of the base class before it gets to an unrecognized element, after which it sends and selects the necessary values ​​elsewhere, which is possible because that it will already have common basic values.

I need to read the principles of serialization ...

+3
source share
2 answers

XmlSerialization is not polymorphic (member attributes, however, come with a declaring class, i.e. if you don't cancel the member with the new keyword (as opposed to override ), you inherit serialization attributes.

Desicialization always leads to the actual type that has been serialized. It really makes a lot of sense.

+2
source

Well, I managed to do what you are trying to do using the DataContractSerializer.

You must either put the KnownTypes attribute in the base classes you want to serialize, or, even better, use the DataContractResolver to search for derived types.

I saw a general implementation on the Internet, I will post it here if I find it again.

Edit

Found here

Let me know if you need more help.

+1
source

All Articles