我有一个名为_updatedComponents的数组,这些对象属于NetworkComponent类.我必须以更改根元素(=数组)的名称和命名空间以及将单个NetworkComponent-item的名称更改为组件的方式对其进行序列化.我有一个代码导致异常:
System.InvalidOperationException: There was an error reflecting type ‘ComponentSyncService.NetworkComponent[]’. —> System.InvalidOperationException: XmlRoot and XmlType attributes may not be specified for the type ComponentSyncService.NetworkComponent[].
码:
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);
解决方法
什么是_updatedComponents?我猜它是一个NetworkComponent [] – 这将使事情变得非常棘手.我建议写一个包装器类型:
public class ComponentsMessage { public NetworkComponent[] Components {get;set;} }
然后,您可以关联正确的属性.如果你需要在NetworkComponent上支持ad-hoc属性,你仍然需要使用属性覆盖(因此我根本没有对上面的内容进行修饰),但ComponentsMessage应该乐于接受属性.
或者,只需编写单独的DTO并映射值.
如果它很简单,您可能只能使用:
[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; } }
或者,如果必须使用属性覆盖,我仍然使用包装器对象:
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); } }