上一篇"学习.NET(6) ISerializable接口简析"中已经分析过如何把Serializable的对象保存到MemoryStream中。通过BitFormatter可以很轻易的把MemoryStream保存为二进制数组中,无论是存为二进制文件,还是保存在数据库等可以存储数据的地方,以便将来可以轻易的Deserialize。当然二进制数据Byte[]总是不方便使用,可以UnicodeEncoding,BitConverter等辅助类可以很容易的把上述二进制数据转化为String,同样可以进行存储以便将来使用。
然而,除了上述方法之外,还有另外一种选择:保存数据到XML文件。
要指定一个Class可以被存储到XML文件,首先要为该Class应用DataContractAttribute。同时为需要保存的Field应用DataMemberAttribute。特别的是,为了Enum数据,可以应用EnumMemberAttribute属性。
以下为简单的测试代码(根据MSDN的示例代码修改而来):
- [DataContract]
- internal enum DisplayLanguage
- {
- [EnumMember(Value = "EN")]
- English = 0,
- [EnumMember(Value = "CN")]
- Chinese = 1,
- }
- [DataContract(Name = "Customer", Namespace = "http://www.google.com")]
- class TESTData : IExtensibleDataObject
- {
- private String strFirst = null;
- private Int32? nTest = null;
- [DataMember()]
- public string FirstName
- {
- get { return strFirst; }
- set { strFirst = value; }
- }
- [DataMember]
- public string LastName;
- [DataMember()]
- public int ID;
- [DataMember()]
- public DisplayLanguage CellDisplay;
- [DataMember()]
- public Int32? TestNumber
- {
- get { return nTest; }
- set { nTest = value; }
- }
- [DataMember()]
- public List<String> listValues = new List<string>();
- public TESTData(string newfName, string newLName, int newID, DisplayLanguage ds)
- {
- FirstName = newfName;
- LastName = newLName;
- ID = newID;
- CellDisplay = ds;
- nTest = null;
- listValues.Add("TEST");
- listValues.Add("Test2");
- }
- private ExtensionDataObject extensionData_Value;
- public ExtensionDataObject ExtensionData
- {
- get
- {
- return extensionData_Value;
- }
- set
- {
- extensionData_Value = value;
- }
- }
- }
以上代码中,我不仅使用了Enum数据,同时使用了Int32?即Nullable<Int32>类型;以及List<String>类型。
以下是测试代码:
- public sealed class Test
- {
- private Test() { }
- public static void Main()
- {
- try
- {
- WriteObject("DataContractSerializerExample.xml");
- ReadObject("DataContractSerializerExample.xml");
- }
- catch (SerializationException serExc)
- {
- Console.WriteLine("Serialization Failed");
- Console.WriteLine(serExc.Message);
- }
- catch (Exception exc)
- {
- Console.WriteLine(
- "The serialization operation failed: {0} StackTrace: {1}",
- exc.Message, exc.StackTrace);
- }
- finally
- {
- Console.WriteLine("Press <Enter> to exit....");
- Console.ReadLine();
- }
- }
- public static void WriteObject(string fileName)
- {
- Console.WriteLine(
- "Creating a Person object and serializing it.");
- TESTData p1 = new TESTData("Zighetti", "Barbara", 101, DisplayLanguage.Chinese);
- p1.FirstName = "Madrid";
- p1.TestNumber = 5;
- FileStream writer = new FileStream(fileName, FileMode.Create);
- DataContractSerializer ser =
- new DataContractSerializer(typeof(TESTData));
- ser.WriteObject(writer, p1);
- writer.Close();
- }
- public static void ReadObject(string fileName)
- {
- Console.WriteLine("Deserializing an instance of the object.");
- FileStream fs = new FileStream(fileName,
- FileMode.Open);
- XmlDictionaryReader reader =
- XmlDictionaryReader.CreateTextReader(fs, new XmlDictionaryReaderQuotas());
- DataContractSerializer ser = new DataContractSerializer(typeof(TESTData));
- // Deserialize the data and read it from the instance.
- TESTData deserializedPerson =
- (TESTData)ser.ReadObject(reader, true);
- reader.Close();
- fs.Close();
- Console.WriteLine(String.Format("{0} {1}, ID: {2}, Display: {3}, Test: {4}",
- deserializedPerson.FirstName, deserializedPerson.LastName,
- deserializedPerson.ID, deserializedPerson.CellDisplay, deserializedPerson.TestNumber == null? "NULL" : deserializedPerson.TestNumber.Value.ToString()));
- }
看看生成的XML文件:
- <Customer xmlns="http://www.google.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><CellDisplay>CN</CellDisplay><FirstName>Madrid</FirstName><ID>101</ID><LastName>Barbara</LastName><TestNumber>5</TestNumber><listValues xmlns:a="http://schemas.microsoft.com/2003/10/Serialization/Arrays"><a:string>TEST</a:string><a:string>Test2</a:string></listValues></Customer>