How to use XmlAttributeOverrides when serializing an array?

I have an array called _updatedComponents of objects of class ClassComponent. I have to serialize it so that the name and namespace of the root element (= array) are changed and the individual name of the NetworkComponent element is changed to a component. I have the code below that throws an exception:

System.InvalidOperationException: An error occurred reflecting the type "ComponentSyncService.NetworkComponent []". ---> System.InvalidOperationException: the XmlRoot and XmlType attributes may not be specified for the type ComponentSyncService.NetworkComponent [].

the code:

XmlAttributeOverrides xaos = new XmlAttributeOverrides(); // the array itself aka the root. change name and namespace XmlElementAttribute xea = new XmlElementAttribute(_updatedComponents.GetType()); xea.Namespace = "http://www.example.com/nis/componentsync"; xea.ElementName = "components"; XmlAttributes xas = new XmlAttributes(); xas.XmlElements.Add(xea); xaos.Add(_updatedComponents.GetType(), xas); // then the items of the array. just change the name xea = new XmlElementAttribute(typeof(networkcomponent)); xea.ElementName = "component"; xas = new XmlAttributes(); xas.XmlElements.Add(xea); xaos.Add(typeof(NetworkComponent), "NetworkComponent", xas); XmlSerializer serializer = new XmlSerializer(_updatedComponents.GetType(), xaos); XmlTextWriter writer = new XmlTextWriter(string.Format("{0}\\ComponentSyncWS_{1}.xml", Preferences.FileSyncDirectory, requestId), Encoding.UTF8); serializer.Serialize(writer, _updatedComponents); 
+6
c # xml-serialization
source share
1 answer

What are _updatedComponents ? I guess this is NetworkComponent[] , which will make things very complex. I would suggest writing a shell type:

 public class ComponentsMessage { public NetworkComponent[] Components {get;set;} } 

Then you can link the correct attributes. If you need to support ad-hoc attributes on NetworkComponent , you still have to use attribute overrides (hence, I didn't decorate it at all above), but ComponentsMessage should happily accept attributes.

Alternatively, just write a separate DTO and map the values.

If it's simple, you can simply use:

 [XmlRoot("components", Namespace = XmlNamespace)] [XmlType("components", Namespace = XmlNamespace)] public class ComponentsMessage { public const string XmlNamespace = "http://www.example.com/nis/componentsync"; [XmlElement("component")] public NetworkComponent[] Components { get; set; } } 

Alternatively, if you must use override attributes, I will still use a wrapper object:

 public class ComponentsMessage { public NetworkComponent[] Components { get; set; } } class Program { static void Main() { NetworkComponent[] _updatedComponents = new NetworkComponent[2] { new NetworkComponent{},new NetworkComponent{} }; const string XmlNamespace = "http://www.example.com/nis/componentsync"; XmlAttributeOverrides ao = new XmlAttributeOverrides(); ao.Add(typeof(ComponentsMessage), new XmlAttributes { XmlRoot = new XmlRootAttribute("components") { Namespace = XmlNamespace }, XmlType = new XmlTypeAttribute("components") { Namespace = XmlNamespace } }); ao.Add(typeof(ComponentsMessage), "Components", new XmlAttributes { XmlElements = { new XmlElementAttribute("component") } }); ComponentsMessage msg = new ComponentsMessage { Components = _updatedComponents }; XmlSerializer serializer = new XmlSerializer(msg.GetType(), ao); serializer.Serialize(Console.Out, msg); } } 
+8
source share

All Articles