2010-12-10 18 views
6

XMLファイルに書き込む必要があるDictionaryオブジェクトがあります。 辞書には、キーとしての文字列型と、カスタムクラスのObject(System.Windows.Forms.Controlから派生)がValueとして含まれています。タイプを反映するエラーが発生しました - XMLシリアル化の問題

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は、クラス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; } 
    //} 
} 
} 

のようなものです。

私がしたいことは、上記の辞書をXMLファイルに書き込むことです。その私がControlSerializerクラス

を使用して、この

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

問題のようにそれを呼び出すことで、私は を言って例外を得ているということですよため

[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(); 
    } 

} 

「エラーが発生しましたタイプ 'SharpFormEditorDemo.ControlSerializer'を反映しています。

しかし、typeof演算子を使用して型を取得しています。なぜこれが起こっているのか困惑した。申し訳ありませんが私はあまりにも長いが、完全な画像を与えたい場合。

おかげ

+0

例外の詳細を投稿する。また、InnerExceptionsについても同様です。 – decyclone

+1

こんにちはDecyclone ...迅速なヘルプのためのthnx内部例外メッセージはこのようなものです。それは私が使用している辞書オブジェクトがシリアライズ可能でないためですか? System.Collections.Generic.Dictionary'2 [System.String、mscorlib、Version = 2.0.0.0、Culture =ニュートラル、PublicKeyToken = b77a5c561934e089]のメンバーSharpFormEditorDemo.ControlSerializer.DicCtrlをシリアル化できません。[SharpFormEditorDemo.CommonControl、SharpFormEditorDemo、Version = 1.0.3996.27187、Culture =ニュートラル、PublicKeyToken = null]]、これはIDictionaryを実装しているためです。 – JCTLK

答えて

10

みんな..

は、代わりに、通常の辞書のSerializableDictionaryオブジェクトを使用していました。私の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

は、私はあなたがXmlSerializer

+1

はいIXMlSerializableインターフェイスを実装するカスタム辞書クラスを使用する必要がありました。 – JCTLK

13

ジェネリック辞書がXmlSerializedすることができないとDictionaryをシリアル化することができないことがわかりますね。取得するエラーは、パブリックプロパティDicCtrlによって発生します。

  • 属性を使用してシリアル化するときにこのプロパティをスキップします(これはおそらく必要ではありません)。
  • プロパティのタイプを、シリアル化可能なタイプに変更します。 List<T>
  • 検索やserializable辞書
  • を実装したり、IXmlSerializable

がBTW [Serializable]属性は、バイナリシリアル化のために必要とされる実装します。 Xmlのシリアル化にはこれを必要としません。私は

[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 

} 

別のクラスを追加する必要がありました、私は解決策を見つけたウェブ上の少しの助けを借りて

+1

ありがとうPeter ...残念ながら、私はそれをシリアル化したいので、この[XMLIgnore]を使用することはできません。とにかく、私はシリアライズ可能な辞書を実装しなければならないと言っています。 – JCTLK

+1

@Janith、既に多くの実装があります。 googleを最初にしてください:) – Ian

+0

@Janith:4番目のオプションとして 'IXmlSerializable'を実装しました。また、@ Ianと同意することに注意してください。もう一つのシリアライズ可能な辞書を作成することは、最高の解決策ではありません。 –

1

DataContractSerializerSystem.Runtime.Serialization.dllから使用しました。私のクラスを疑問のない2つの辞書プロパティで直列化/逆直列化しました。

関連する問題