C#serialize包含XML中另一个序列化对象的对象

时间:2016-12-09 22:26:55

标签: c# xml

任何人都可以理解为什么C#无法反序列化这个xml文件:

[Serializable()]
    public class SerializableDictionary<TKey, TVal> : Dictionary<TKey, TVal>, IXmlSerializable, ISerializable {
        private const string DictionaryNodeName = "Dictionary";
        private const string ItemNodeName = "Item";
        private const string KeyNodeName = "Key";
        private const string ValueNodeName = "Value";

        public SerializableDictionary() {
        }

        public SerializableDictionary(IDictionary<TKey, TVal> dictionary)
            : base(dictionary) {
        }

        public SerializableDictionary(IEqualityComparer<TKey> comparer)
            : base(comparer) {
        }

        public SerializableDictionary(int capacity)
            : base(capacity) {
        }

        public SerializableDictionary(IDictionary<TKey, TVal> dictionary, IEqualityComparer<TKey> comparer)
            : base(dictionary, comparer) {
        }

        public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer)
            : base(capacity, comparer) {
        }

        protected SerializableDictionary(SerializationInfo info, StreamingContext context) {
            int itemCount = info.GetInt32("ItemCount");
            for (int i = 0; i < itemCount; i++) {
                KeyValuePair<TKey, TVal> kvp = (KeyValuePair<TKey, TVal>)info.GetValue(String.Format("Item{0}", i), typeof(KeyValuePair<TKey, TVal>));
                this.Add(kvp.Key, kvp.Value);
            }
        }

        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
            info.AddValue("ItemCount", this.Count);
            int itemIdx = 0;
            foreach (KeyValuePair<TKey, TVal> kvp in this) {
                info.AddValue(String.Format("Item{0}", itemIdx), kvp, typeof(KeyValuePair<TKey, TVal>));
                itemIdx++;
            }
        }


        void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer) {
            //writer.WriteStartElement(DictionaryNodeName);
            foreach (KeyValuePair<TKey, TVal> kvp in this) {
                writer.WriteStartElement(ItemNodeName);
                writer.WriteStartElement(KeyNodeName);
                KeySerializer.Serialize(writer, kvp.Key);
                writer.WriteEndElement();
                writer.WriteStartElement(ValueNodeName);
                ValueSerializer.Serialize(writer, kvp.Value);
                writer.WriteEndElement();
                writer.WriteEndElement();
            }
            //writer.WriteEndElement();
        }

        void IXmlSerializable.ReadXml(System.Xml.XmlReader reader) {
            if (reader.IsEmptyElement) {
                return;
            }

            // Move past container
            if (!reader.Read()) {
                throw new XmlException("Error in Deserialization of Dictionary");
            }

            //reader.ReadStartElement(DictionaryNodeName);
            while (reader.NodeType != XmlNodeType.EndElement) {
                reader.ReadStartElement(ItemNodeName);
                reader.ReadStartElement(KeyNodeName);
                TKey key = (TKey)KeySerializer.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadStartElement(ValueNodeName);
                TVal value = (TVal)ValueSerializer.Deserialize(reader);
                reader.ReadEndElement();
                reader.ReadEndElement();
                this.Add(key, value);
                reader.MoveToContent();
            }
            //reader.ReadEndElement();

            reader.ReadEndElement(); // Read End Element to close Read of containing node
        }

        System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() {
            return null;
        }

        protected XmlSerializer ValueSerializer {
            get {
                if (valueSerializer == null) {
                    valueSerializer = new XmlSerializer(typeof(TVal));
                }
                return valueSerializer;
            }
        }

        private XmlSerializer KeySerializer {
            get {
                if (keySerializer == null) {
                    keySerializer = new XmlSerializer(typeof(TKey));
                }
                return keySerializer;
            }
        }

        private XmlSerializer keySerializer = null;
        private XmlSerializer valueSerializer = null;
    }

它包含一个序列化字典,对于每个键,该值是一个序列化对象。如果值不是序列化对象,则字典可以正常工作。

使用XMLSerializer序列化序列化值和外部字典。

这是班级:

private SerializableDictionary<string, bool> alreadySeen;
...
public override object Snapshot(int snapshotId) {
            XmlSerializer serializer = new XmlSerializer(typeof(SerializableDictionary<string, bool>));
            StringWriter writer = new StringWriter();
            serializer.Serialize(writer, alreadySeen);

            return writer.ToString();
}

反序列化外部字典时出现问题。 感谢

更新:更多代码

以下是我生成字典值的方法:

public override Snapshot Snapshot(int snapshotId) {
    var snapshot = new KeyedSnapshot(snapshotId);

    // OperatorStatePerKey is a SerializableDictionary<string, object>
    foreach (KeyValuePair<string, Operation> op in operations) {
        snapshot.OperatorStatePerKey.Add(op.Key, op.Value.Snapshot(snapshotId)); // Here I'm calling the Snapshot function 
    }

    return snapshot;
}

...

// Will serialize the Snapshot(1)
snapshotStore.Store(replicaId, Snapshot(1) as KeyedSnapshot);

以下是我在字典中插入序列化值的方法:

 public void Store(int replicaId, KeyedSnapshot snapshot) {
    // Serialize the snapshot and write it to a file
    var xmlSerializer = new XmlSerializer(typeof(KeyedSnapshot));
    var writer = new StreamWriter(prefix + replicaId + "." + snapshot.SnapshotId + ".snp", false);
    xmlSerializer.Serialize(writer, snapshot);
    writer.Close();
}

这是snapshotStore.Store实现:

    XmlSerializer xmlSerializer = new XmlSerializer(typeof(KeyedSnapshot));
    StreamReader reader = new StreamReader(filename);

    // The error happens here
    KeyedSnapshot k = (KeyedSnapshot)xmlSerializer.Deserialize(reader);

这就是我反序列化的方式:

System.InvalidOperationException: There is an error in XML document (2, 2). ---> System.InvalidOperationException: <NonKeyedSnapshot xmlns=''> was not expected.
  at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderKeyedSnapshot.Read4_KeyedSnapshot () [0x00064] in <ea86d900c5124263b557de9cd4c57fb0>:0
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00038] in <8f2c484307284b51944a1a13a14c0266>:0
   --- End of inner exception stack trace ---
  at System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.XmlReader xmlReader, System.String encodingStyle, System.Xml.Serialization.XmlDeserializationEvents events) [0x00139] in <1140eab9e72948548294172a9716416d>:0
  at System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.XmlReader xmlReader, System.String encodingStyle) [0x00000] in <1140eab9e72948548294172a9716416d>:0
  at System.Xml.Serialization.XmlSerializer.Deserialize (System.IO.TextReader textReader) [0x0001c] in <1140eab9e72948548294172a9716416d>:0
  at Task.Core.KeyedStateSnapshotStore.Retrieve (System.Int32 snapshotId) [0x0008b] in <3fdb7e68af394b91885b9dfe6ed8ba76>:0

最后,这是一个例外:

{{1}}

0 个答案:

没有答案