InvalidOperationException When XML Serializing Inherited Class

I had a problem serializing a C # class in an XML file that has a base class ... here is a simple example:

namespace Domain { [Serializable] public class ClassA { public virtual int MyProperty { get; set; } } } namespace Derived { public class ClassA : Domain.ClassA { public override int MyProperty { get { return 1; } set { /* Do Nothing */ } } } } 

When I try to serialize an instance of Derived.ClassA, I get the following exception:

InvalidOperationException (types “Domain.ClassA” and “Derived.ClassA” use the XML type name “ClassA” from the namespace. Use XML attributes to specify a unique XML name and / or namespace for this type.)

The problem is that I want to create one base class that simply defines the structure of the XML file, and then allows someone from this class to extract from this class to insert business rules, but formatting will come from the database.

Is this possible, and if so, how can I specify a base class for this?

+4
source share
6 answers

If you can rename derived classes to something other than their base class, you can use XmlAttributeOverrides to do this

 // For ClassB, which derives from ClassA XmlAttributes attributes = new XmlAttributes(); attributes.XmlRoot = new XmlRootAttribute("ClassA"); XmlAttributeOverrides overrides = new XmlAttributeOverrides(); overrides.Add(typeof(ClassB), attributes); XmlSerializer serializer = new XmlSerializer(typeof(ClassB), overrides); 

This will serialize to <ClassA> ... </ClassA> and can be serialized from this to instances of ClassB .

As far as I can tell, there is no way to do this when the base and the derived classes have the same name (with the exception of full control over the serialization process using the “Data Contract Surrogates” or some other overkill method).

+2
source

It helped us.

 [XmlType(TypeName = "DerivedClassA")] 
+5
source

I think your derived class should also be marked with the [Serializable] attribute for serialization / deserialization.

In addition to the serializable attribute, you also need to make one of two that have a different XML name - as the error says, in the "XML world" they are both called "ClassA". One of them should be named differently using the XmlElement attribute (if you use XmlSerializer - right?)

 namespace Domain { [Serializable] [XmlElement(ElementName="ClassABase")] public class ClassA { public virtual int MyProperty { get; set; } } } namespace Derived { [Serializable] public class ClassA : Domain.ClassA { public override int MyProperty { get { return 1; } set { /* Do Nothing */ } } } } 

Mark

0
source

Set the base namespace for your domain and set the name of the custom item for the derived class:

 namespace Domain { [Serializable] [XmlRoot(Namespace = "http://mynamespace/domain/2009/")] public class ClassA { [XmlIgnore] public virtual int MyProperty { get; set; } } } namespace Derived { [Serializable] [XmlRoot(ElementName = "DerivedClassA")] public class ClassA : Domain.ClassA { public override int MyProperty { get { return 1; } set { base.MyProperty = value; } } } } 
0
source

I had the same problem, but with an additional restriction: there is no access to the source for the Domain or Derived classes. A derived object inherited from a Domain object, and since classes have the same unqualified name, the XmlSerializer will not be able to serialize an object of the Derived class.

Perhaps this could be resolved with brute force (changing the IL for one of the classes to add the appropriate attributes), but I need something “cleaner”. Here's what worked:

 var attrs = new XmlAttributes(); attrs.XmlType = new XmlTypeAttribute("anythingButClassA"); var overrides = new XmlAttributeOverrides(); overrides.Add(typeof(Domain.ClassA), attrs); var serializer = new XmlSerializer(typeof(Derived.ClassA), overrides); serializer.Serialize(Console.Out, new Derived.ClassA()); 

Even if you are the author of the Domain and / or Derived classes, this way you do not need to rename them.

0
source

This is merely informative, as it does not provide a concrete answer, but here is a good article from the July version of MSDN about discussing these name conflicts. "XML namespace collisions, XmlNodeList and Deserialization, and more . "

0
source

All Articles