【问题标题】:There was an error reflecting type - XML Serialization issue反映类型时出现错误 - XML 序列化问题
【发布时间】:2010-12-10 09:10:30
【问题描述】:

我有一个需要写入 XML 文件的 Dictionary 对象。 字典包含字符串类型作为键和自定义类的对象(派生自 System.Windows.Forms.Control )作为值。

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 运算符获取类型。对为什么会发生这种情况感到困惑。对不起,如果我太长了,但想给出完整的图片。

谢谢

【问题讨论】:

  • 发布有关异常的更多详细信息。对于任何 InnerExceptions 也是如此。
  • 嗨 Decyclone... thnx 提示帮助内部异常消息是这样的。是因为我使用的字典对象不可序列化吗?无法序列化 System.Collections.Generic.Dictionary`2 [[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[SharpFormEditorDemo.CommonControl, SharpFormEditorDemo, Version 类型的成员 SharpFormEditorDemo.ControlSerializer.DicCtrl =1.0.3996.27187, Culture=neutral, PublicKeyToken=null]],因为它实现了 IDictionary。

标签: c# .net xml serialization


【解决方案1】:

不能对通用字典进行 XmlSerialized。你得到的错误是由公共属性DicCtrl引起的。

  • 序列化时使用[XmlIgnore] 属性跳过此属性(这可能不是您想要的)。
  • 将属性的类型更改为可以序列化的类型,例如List&lt;T&gt;
  • 查找或实现可序列化字典
  • 或者实现IXmlSerializable

顺便说一句,[Serializable] 属性仅用于二进制序列化。 Xml 序列化不需要它。

【讨论】:

  • 谢谢彼得...不幸的是我不能使用这个 [XMLIgnore] 因为我想序列化它。无论如何,正如你所说,我将不得不实现一个可序列化的字典。
  • @Janith,已经有很多实现了。一定要先用谷歌搜索:)
  • @Janith:我添加了实现IXmlSerializable 作为第四个选项。另请注意,我同意@Ian 的观点,即创建另一个可序列化字典似乎不是最好的解决方案
【解决方案2】:

伙计们..在网络上的一些帮助下,我找到了解决方案..

我不得不添加另一个类

[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

现在一切正常。谢谢大家。 !!!

【讨论】:

    【解决方案3】:

    我想你会发现Dictionary不能用XmlSerializer序列化

    【讨论】:

    • 是的,我必须使用实现 IXMlSerializable 接口的自定义字典类。
    【解决方案4】:

    我使用来自System.Runtime.Serialization.dllDataContractSerializer。使用两个 Dictionary 属性对我的类进行序列化/反序列化,没有任何问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 2013-04-05
      • 2020-01-08
      相关资源
      最近更新 更多