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

前端之家收集整理的这篇文章主要介绍了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);
    }
}

猜你在找的C#相关文章