有一个错误反映了类型 - XML序列化问题

时间:2010-12-10 09:10:31

标签: c# .net xml serialization

我有一个需要写入XML文件的Dictionary对象。 字典包含String类型作为Key,自定义类的Object(从System.Windows.Forms.Control派生)作为Value。

namespace SharpFormEditorDemo
{
    [Serializable]
    public static class common
    {

    public static Dictionary<String,CommonControl > dicControls = new Dictionary<string, CommonControl>();

    public static Object objSelected = new Object();
    public static int ctrlId = 0;

    //The serialization and Deserialization methods.
    public static void Serialize(XmlTextWriter xmlTextWriter,Dictionary<String,CommonControl> dic)
    {
        xmlTextWriter.WriteStartDocument();
        ControlSerializer file = new ControlSerializer(dic);
        XmlSerializer xmlSerializer = new XmlSerializer(typeof(ControlSerializer));
        xmlSerializer.Serialize(xmlTextWriter, file);

        xmlTextWriter.WriteEndDocument();
    }
}

类CommonControl就像这样

namespace SharpFormEditorDemo
{

public class CommonControl : System.Windows.Forms.Control 
{

    //private List<String> controls;
    private String sql;
    private int minVal; //Minimum value for a field
    private int maxVal; //Maximum value for a field
    private string displayValue; //Display Value        
    private string keyValue; //Key Value
    private string clickEvent; //Click event
    private string selectedIndexChangeEvent; //Combo box event.
    private string validateEvent; //Validated event.



    public string SelectedIndexChangeEvent
    {
        get { return selectedIndexChangeEvent; }
        set { selectedIndexChangeEvent = value; }
    }

    public string ClickEvent
    {
        get { return clickEvent; }
        set { clickEvent = value; }
    }

    public string ValidateEvent
    {
        get { return validateEvent; }
        set { validateEvent = value; }
    }

    public string KeyValue
    {
        get { return keyValue; }
        set { keyValue = value; }
    }

    public string DisplayValue
    {
        get { return displayValue; }
        set { displayValue = value; }
    }

    public int MinVal
    {
        get { return minVal; }
        set { minVal = value; }
    }       

    public int MaxVal
    {
        get { return maxVal; }
        set { maxVal = value; }
    }     

    public String Sql
    {
        get { return sql; }
        set { sql = value; }
    }

    //public List<String> Controls
    //{
    //    get { return controls; }
    //    set { controls = value; }
    //}
}
}

类CommonControl派生自Controls类。

我想要做的是将上述字典写入XML文件。

[Serializable]
public class ControlSerializer : ISerializable
{
    public ControlSerializer()
    {
    }


    private Dictionary<String, CommonControl> dicCtrl;

    public Dictionary<String, CommonControl> DicCtrl
    {
        get { return dicCtrl; }
        set { dicCtrl = value; }
    }


    public ControlSerializer(Dictionary<String, CommonControl> dic)
    {           
        this.DicCtrl = dic;
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        throw new NotImplementedException();
    }

}

因为我正在使用ControlSerializer类

并称之为

 try
        {
            XmlTextWriter xlw = new XmlTextWriter(@"D:\Test.xml", null);
            common.Serialize(xlw, common.dicControls);
        }
        catch (Exception exShow)
        {

问题是我得到一个例外 “有一个错误反映了'SharpFormEditorDemo.ControlSerializer'类型。”

但我正在使用typeof运算符获取类型。感到困惑的是为什么会这样。对不起如果我太冗长但想要全面了解。

由于

4 个答案:

答案 0 :(得分:13)

通用词典不能是XmlSerialized。您获得的错误是由公共财产DicCtrl引起的。

  • 使用[XmlIgnore]属性在序列化时跳过此属性(可能不是您想要的)。
  • 将属性的类型更改为可以序列化的类型,例如List<T>
  • 查找或实现可序列化词典
  • 或实施IXmlSerializable

BTW [Serializable]属性仅用于二进制序列化。你不需要它来进行Xml序列化。

答案 1 :(得分:10)

伙计们......在网上给我一点帮助,我找到了一个解决方案..

我必须添加另一个类

[XmlRoot("dictionary")]
public class SerializableDictionary<TKey, TValue>: Dictionary<TKey, TValue>, IXmlSerializable
{      

    #region IXmlSerializable Members
    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }


    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); 

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read(); 

        if (wasEmpty)
            return; 

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");
            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();
            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();
            this.Add(key, value);
            reader.ReadEndElement();
            reader.MoveToContent();
        }

        reader.ReadEndElement();
    }



    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue)); 

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");
            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();
            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();
            writer.WriteEndElement();
        }

    }

    #endregion

}

然后使用SerializableDictionary对象而不是普通的Dictionary。同样在我的CommonControls类中,我必须使用以下方法实现“IXmlSerializable”。

 #region IXmlSerializable Members

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        throw new NotImplementedException();
    }

    public void ReadXml(XmlReader reader)
    {
        throw new NotImplementedException();
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotImplementedException();
    }

    #endregion

现在整个工作正常。感谢大家。 !!!

答案 2 :(得分:2)

我认为您会发现无法使用Dictionary序列化XmlSerializer

答案 3 :(得分:1)

我使用了来自DataContractSerializer的{​​{1}}。使用两个Dictionary属性对我的类进行序列化/反序列化,没有任何问题。