"XML attributes may not be specified for the type"XmlSerializer and CollectionBase derived classesI get this error when I try to serialize an object that is based upon the CollectionBase class and has an XmlRoot attribute.
The solution is to provide hints in the Serialization method to add a defined root in the generated XML. Thanks to user "armanddp"
http://dotnet.org.za/armand/archive/2004/09/21/4164.aspx, I have beautified his solution as shown below:
Step 1: Create an attribute class that you can use to specifiy the root attribute.
[AttributeUsage(AttributeTargets.Class)] public class XmlRootNameAttribute : Attribute { public XmlRootNameAttribute() {} public XmlRootNameAttribute(string name) { this.name = name; } public string name = string.Empty; }Step 2: Add the attribute to your own class.
[Serializable][XmlRootName("StepClassConfigurationCollection")]public class MyCollection : CollectionBase, IList {}Step 3: Create a Serializer method to read the extra attribute, if it exists, otherwise serialise as per normal.
/// <summary> /// Serialize the given object into a string /// </summary> /// <param name="o"></param> /// <returns></returns> public string SerializeObject(object o) { string ret = string.Empty; Stream writer = new MemoryStream(); XmlSerializer ser = null; XmlRootAttribute ra = new XmlRootAttribute(); Type objectType = o.GetType(); // determines if the custom attribute was found bool bAttFound = false; ra.Namespace = string.Empty; // try and find the custom attribute that will determine the root namespace. object [] oAtt = objectType.GetCustomAttributes(typeof(PMPDO.XmlRootNameAttribute), false); if (oAtt != null) { if (oAtt.Length > 0) { bAttFound = true; // use the given root name ra.ElementName = ((PMPDO.XmlRootNameAttribute)oAtt[0]).name; } } if (!bAttFound) { // if there is no root name provided, then just use the default ser = new XmlSerializer(objectType); } else { // otherwise use the provided root name ser = new XmlSerializer(objectType, ra); } XmlSerializerNamespaces ns = new XmlSerializerNamespaces(); ns.Add("",""); if (bAttFound) { // use the given root when provided ser.Serialize(writer, o, ns); } else { // otherwise use the default (no root provided) ser.Serialize(writer, o); } // read the string from the serialized stream writer.Position = 0; StreamReader sr = new StreamReader(writer,System.Text.Encoding.ASCII); ret = sr.ReadToEnd(); return ret; }