Summary
When using the XmlSerializer
class, serializing a List
(where T can be serialized with XmlSerialize
Your problem is that you are trying to use overrides to attach [XmlArray] and [XmlArrayItem] to the type List<T>
. However, as shown in the docs, [XmlArray]
cannot be used in this manner:
[AttributeUsageAttribute(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = false)] public class XmlArrayAttribute : Attribute
Notice there is no AttributeTargets.Class included? That means that [XmlArray]
cannot be applied directly to a type and so attempting to do so via XML overrides rightly throws an exception.
But as to why that exception message states,
System.InvalidOperationException: XmlRoot and XmlType attributes may not be specified for the type System.Collections.Generic.List`1...
Er, well, that message is simply wrong. It would appear to be a minor bug in XmlSerializer
. You could even report it to Microsoft if you want.
What you need to do instead is:
Override the [XmlRoot] attribute of List<T>
to specify the desired name, in this case "texparams", AND
Override the [XmlType] attribute of T
and set XmlTypeAttribute.TypeName to be the desired collection element name. In the absence of an [XmlArrayItem(name)]
override this is what controls the element names of collections whose items are of type T
.
Thus your code should look like:
static XmlSerializer MakeListSerializer<T>(string rootName, string elementName)
{
xmls.XmlAttributeOverrides attributeOverrides = new xmls.XmlAttributeOverrides();
attributeOverrides.Add(typeof(List<T>), new xmls.XmlAttributes()
{
XmlRoot = new xmls.XmlRootAttribute(rootName),
});
attributeOverrides.Add(typeof(T), new xmls.XmlAttributes()
{
XmlType = new xmls.XmlTypeAttribute(elementName),
});
return new XmlSerializer(typeof(List<T>), attributeOverrides);
}
Sample fiddle.
Note that when constructing an XmlSerializer
using XmlAttributeOverrides
you must cache the serializer for later reuse to avoid a severe memory leak, for reasons explained here.