c# – 序列化数组时如何使用XmlAttributeOverrides?

我有一个名为_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);
    }
}

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...