XML序列化
XmlSerializer xmlSer = new XmlSerializer(typeof(Class1)); MemoryStream writer = new MemoryStream(); Class1 c2 = new Class1(); c2.b = "123"; c2.c = 333; c2.cc = new Class2[2]; c2.cc[0] = new Class2(); c2.cc[0].bb = 223; c2.cc[1] = new Class2(); c2.cc[1].bb = 555; xmlSer.Serialize(writer, c2); StreamReader sr = new StreamReader(writer); var str = Encoding.UTF8.GetString(writer.ToArray()); Console.WriteLine(str); Console.ReadLine(); writer.Flush(); writer.Close();
反序列化
XmlSerializer serializer = new XmlSerializer(typeof(Class1)); TextReader reader = new StringReader(str); Class1 c1 = (Class1)serializer.Deserialize(reader);
附上序列化助手类
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Xml.Serialization; namespace Hont { public static class XmlSerializableHelper { #region Memory public static T DeSerializerFromMemory<T>(Stream stream) { XmlSerializer xmlSer = new XmlSerializer(typeof(T)); return (T)xmlSer.Deserialize(stream); } public static Stream SerializerToMemory(object obj) { XmlSerializer xmlSer = new XmlSerializer(obj.GetType()); MemoryStream writer = new MemoryStream(); xmlSer.Serialize(writer, obj); return writer; } #endregion #region Disk public static T DeSerializerFromDisk<T>(string path) { return DeSerializerFromString<T>(File.ReadAllText(path)); } public static void SerializerToDisk(string path, object obj, Encoding encoding) { var serResult = SerializerToString(obj); if (File.Exists(path)) File.Delete(path); File.AppendAllText(path, serResult, encoding); } #endregion #region String public static T DeSerializerFromString<T>(string xml) { XmlSerializer xmlSer = new XmlSerializer(typeof(T)); TextReader reader = new StringReader(xml); return (T)xmlSer.Deserialize(reader); } public static string SerializerToString(object obj) { XmlSerializer xmlSer = new XmlSerializer(obj.GetType()); MemoryStream writer = new MemoryStream(); xmlSer.Serialize(writer, obj); StreamReader sr = new StreamReader(writer); var str = Encoding.UTF8.GetString(writer.ToArray()); writer.Flush(); writer.Close(); sr.Close(); return str; } #endregion } }
需要注意几点:
1.需要无参数的构造函数
2.对于不可序列化的复杂类型,用特殊特性去标记,并实现序列化接口,具体msdn查询IXmlSerializable
3.不支持只读字段的序列化。
4.微软自己的序列化,对可空类型的支持比较糟糕。尽量避免序列化可空类型
5.[System.Xml.Serialization.XmlIgnore]可以使成员忽略序列化
6.不支持字典类型,但网上有一个扩展"可序列化字典":
using System; using System.Collections.Generic; using System.Runtime.Serialization; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; namespace SerializableDictionary { [XmlRoot("dictionary"), Serializable] public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable { public SerializableDictionary() { } public SerializableDictionary(IDictionary<TKey, TValue> dictionary) : base(dictionary) { } public SerializableDictionary(IEqualityComparer<TKey> comparer) : base(comparer) { } public SerializableDictionary(int capacity) : base(capacity) { } public SerializableDictionary(int capacity, IEqualityComparer<TKey> comparer) : base(capacity, comparer) { } protected SerializableDictionary(SerializationInfo info, StreamingContext context) : base(info, context) { } #region IXmlSerializable Members public XmlSchema GetSchema() { return null; } /// <summary> /// 从对象的 XML 表示形式生成该对象 /// </summary> /// <param name="reader"></param> public void ReadXml(XmlReader reader) { var keySerializer = new XmlSerializer(typeof(TKey)); var valueSerializer = new XmlSerializer(typeof(TValue)); bool wasEmpty = reader.IsEmptyElement; reader.Read(); if (wasEmpty) return; while (reader.NodeType != XmlNodeType.EndElement) { reader.ReadStartElement("item"); reader.ReadStartElement("key"); var key = (TKey)keySerializer.Deserialize(reader); reader.ReadEndElement(); reader.ReadStartElement("value"); var value = (TValue)valueSerializer.Deserialize(reader); reader.ReadEndElement(); Add(key, value); reader.ReadEndElement(); reader.MoveToContent(); } reader.ReadEndElement(); } /// <summary> /// 将对象转换为其 XML 表示形式 /// </summary> /// <param name="writer"></param> public void WriteXml(XmlWriter writer) { var keySerializer = new XmlSerializer(typeof(TKey)); var valueSerializer = new XmlSerializer(typeof(TValue)); foreach (TKey key in 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 } }
7.支持抽象类的序列化
8.ArrayList和Hashtable以及System.Collections的常规集合类型都支持的不太好。ArrayList只支持值类型,不支持结构。
9.报错InvalidOperationException: The type of the argument object 'xxx' is not primitive.,解决方法xml不知道实际的弱类型,你需要传过去。如下:
var xmlSer = new XmlSerializer(list.GetType(), new System.Type[] { typeof(A1), typeof(A2) });
10.可以序列化属性,但必须是Get,Set的