使用c# . net 2.0,我有一个组合数据类,它确实有[Serializable]属性。我正在创建一个XMLSerializer类并将其传递到构造函数中:

XmlSerializer serializer = new XmlSerializer(typeof(DataClass));

我得到一个异常说:

有错误反射类型。

在数据类内部有另一个复合对象。这是否也需要有[Serializable]属性,或者通过将它放在顶部对象上,它是否递归地应用到内部的所有对象?


当前回答

[System.Xml.Serialization.XmlElementAttribute("strFieldName", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]

Or

[XmlIgnore]
string [] strFielsName {get;set;}

其他回答

如果需要处理特定的属性(例如Dictionary或任何类),可以实现IXmlSerialiable接口,这将为您提供更大的自由,但代价是编写更冗长的代码。

public class NetService : IXmlSerializable
{
    #region Data

        public string Identifier = String.Empty;

        public string Name = String.Empty;

        public IPAddress Address = IPAddress.None;
        public int Port = 7777;

    #endregion

    #region IXmlSerializable Implementation

        public XmlSchema GetSchema() { return (null); }

        public void ReadXml(XmlReader reader)
        {
            // Attributes
            Identifier = reader[XML_IDENTIFIER];
            if (Int32.TryParse(reader[XML_NETWORK_PORT], out Port) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_PORT);
            if (IPAddress.TryParse(reader[XML_NETWORK_ADDR], out Address) == false)
            throw new XmlException("unable to parse the element " + typeof(NetService).Name + " (badly formatted parameter " + XML_NETWORK_ADDR);
        }

        public void WriteXml(XmlWriter writer)
        {
            // Attributes
            writer.WriteAttributeString(XML_IDENTIFIER, Identifier);
            writer.WriteAttributeString(XML_NETWORK_ADDR, Address.ToString());
            writer.WriteAttributeString(XML_NETWORK_PORT, Port.ToString());
        }

        private const string XML_IDENTIFIER = "Id";

        private const string XML_NETWORK_ADDR = "Address";

        private const string XML_NETWORK_PORT = "Port";

    #endregion
}

有一篇有趣的文章展示了一种优雅的方法来实现“扩展”XmlSerializer的复杂方法。


文章说:

IXmlSerializable在官方文档中有介绍,但是文档声明它不打算供公众使用,并且没有提供其他信息。这表明开发团队希望保留修改、禁用甚至完全删除此可扩展性钩子的权利。然而,只要你愿意接受这种不确定性,并处理未来可能发生的变化,你就没有理由不能利用它。

因此,我建议实现您自己的IXmlSerializable类,以避免实现过于复杂。

...使用反射实现自定义XmlSerializer类可能很简单。

序列化图中的所有对象都必须是可序列化的。

由于XMLSerializer是一个黑盒,如果您想进一步调试序列化过程,请检查这些链接。

更改XmlSerializer输出临时程序集的位置

如何:调试到.NET XmlSerializer生成的程序集

还要注意,您不能序列化用户界面控件,并且您想传递到剪贴板上的任何对象都必须是可序列化的,否则就不能传递给其他进程。

到目前为止,我有一个稍微不同的解决方案,所以对于任何未来的文明,这里是我的!

我已经声明了一个“时间”的数据类型,因为原始类型是TimeSpan,随后更改为字符串:

[System.Xml.Serialization.XmlElementAttribute(DataType="time", Order=3)]

然而,实际的类型是字符串

public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

通过删除DateType属性,Xml可以被序列化

[System.Xml.Serialization.XmlElementAttribute(Order=3)]
public string TimeProperty {
    get {
        return this.timePropertyField;
    }
    set {
        this.timePropertyField = value;
        this.RaisePropertyChanged("TimeProperty");
    }
}

我最近在添加一个新属性时在一个web引用部分类中得到了这个。自动生成的类添加了以下属性。

    [System.Xml.Serialization.XmlElementAttribute(Order = XX)]

我需要添加一个类似的属性,其顺序比自动生成序列中的最后一个高,这为我修复了它。