Reputation: 23615
I'm using this code
XmlSerializer xs = new XmlSerializer(typeof(T));
To serialize an object.
Now I get an error on this line of code (which is in an object nested way down in the to be serialized object)
public override List<BrokenRule> GetBrokenRules() {
the error is Csla.Validation.BrokenRule cannot be serialized because it does not have a parameterless constructor.
Now that is correct, but I thought methods
were not serialized, so what is the problem (the Csla.Validation.BrokenRule
is not used elsewhere)
If it is by design, this behavior, is there a way to runtime say "ignore this part of the object"?
Editing the objects code with attributes etc. is not allowed....
Upvotes: 0
Views: 448
Reputation: 116785
One way you could serialize this class to XML is to create an XmlSerializer
for the derived class and pass XmlAttributeOverrides
that specify that the property which returns a class is XmlIgnore
. However, as specified in the documentation, you must cache and re-use this XmlSerializer
:
To increase performance, the XML serialization infrastructure dynamically generates assemblies to serialize and deserialize specified types. The infrastructure finds and reuses those assemblies. This behavior occurs only when using the following constructors:
XmlSerializer.XmlSerializer(Type)
XmlSerializer.XmlSerializer(Type, String)
If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable, as shown in the following example.
Rather than a HashTable
, in simple cases I will construct my XmlSerializer
in the static constructor for the class I need to serialize. This is fairly lazy, and is guaranteed to be thread safe. Thus, for instance:
public class NoParameterlessConstructor
{
public string Value { get; set; }
public NoParameterlessConstructor(string value)
{
this.Value = value;
}
}
public class BaseClass
{
public NoParameterlessConstructor NoParameterlessConstructor { get; set; }
}
public class DerivedClass : BaseClass
{
static XmlSerializer serializer = null;
static DerivedClass()
{
var xOver = new XmlAttributeOverrides();
var attrs = new XmlAttributes() { XmlIgnore = true };
xOver.Add(typeof(BaseClass), "NoParameterlessConstructor", attrs); // Must use BaseClass here not DerivedClass!
serializer = new XmlSerializer(typeof(DerivedClass), xOver);
}
public static XmlSerializer DerivedClassXmlSerializer { get { return serializer; } }
public int Id { get; set; }
}
And then, to test:
public static class TestNoParameterlessConstructor
{
public static void Test()
{
var derived = new DerivedClass { Id = 1, NoParameterlessConstructor = new NoParameterlessConstructor("Test") };
var xml = XmlSerializationHelper.GetXml(derived, DerivedClass.DerivedClassXmlSerializer);
Debug.WriteLine(xml);
}
}
which outputs
<?xml version="1.0" encoding="utf-16"?>
<DerivedClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Id>1</Id>
</DerivedClass>
Upvotes: 1