有一个错误的反射式 - XML序列化问题有一个、错误、序列化、反射式

2023-09-03 02:08:56 作者:铁骨铮铮女汉子

我有需要被写入到一个XML文件中的Dictionary对象。 该字典包含字符串类型的键和自定义类的对象为值(从派生)。

I have a Dictionary object which needs to be written into an XML file. The dictionary contains String type as Key and a custom class's Object (Deriving from System.Windows.Forms.Control ) as 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是这样的

The class CommonControl is like this

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是控制类派生。

The class CommonControl is a deriving from Controls class.

我想要做的就是写上面说的词典到一个XML文件中。

What I want to do is to write the Above said dictionary to an XML file.

[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类

for that I'm using the ControlSerializer class

而在调用它像这样

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

问题是,我发现了一个异常的说法 有一个错误反映类型'SharpFormEditorDemo.ControlSerializer'。

The problem is that I'm getting an exception saying "There was an error reflecting type 'SharpFormEditorDemo.ControlSerializer'."

但我发现了使用typeof运算符的类型。百思不得其解,为什么这种情况正在发生。很抱歉,如果我太冗长,但想给的全貌。

But I'm getting the type using typeof operator. Baffled on why this is happening. Sorry If I'm too lengthy but wanted to give the full picture.

感谢

推荐答案

家伙..随着web上的一点帮助我找到了解决办法。

Guys.. With a little help on web I found a solution..

我不得不添加其他类

[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对象来代替。此外,在我的CommonControls I类必须实现的IXmlSerializable用下面的方法。

Then used the SerializableDictionary object instead of normal Dictionary. Also in my CommonControls class I had to implement "IXmlSerializable" with following methods.

 #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

现在整个事情是工作确定。谢谢大家。 !

Now the whole thing is working ok. Thanks Everyone. !!!