C# DataContract serialization 序列化

2014-07-02  籽藤 

序列化是编程中很常见的一项工作,尤其是xml文件和对象之间的序列化。这几天看《Head First C# 2nd Edition》练手,发觉之前对DataContract序列化还不熟悉,之前都是用[Serializable]标签进行序列化(XmlSerializer)比较多。

The Data Contract Serializer used by default in WCF does not support XML attributes (for performance reasons - the DCS is about 10% faster on average than the XML serializer).

So if you really want to use the DCS, you cannot use this structure you have - you would have to change it.

Or you need to use the XmlSerializer with WCF, as Greg showed in his answer - that works, too, but you loose the performance benefit (plus all other benefits) of the DCS.

摘自:http://stackoverflow.com/questions/4858798/datacontract-xml-serialization-and-xml-attributes/4859084#4859084

撇开书上的例子不谈(因为没有涉及集合,比较简单),网上很多例子都是只贴C#代码,没有附上相应的xml文件,新手的困惑可能比较多。于是我又写了个小例子。

  • xml数据源是必应词典导出的个人单词本

  • 程序先用linq to xml方式读出单词列表,再用DataContractSerializer写入,之后读取。

值得注意的是,示例输出的xml文件中会定义xmlns属性。即:xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication3" 这正是DataContractSerializer和XmlSerializer不同;如果不想输出xmlns,还是用XmlSerializer写xml文件吧。这个问题,在《Pro Windows Phone App Development, 3rd Edition》第11章的"Handling XML Namespace Issues"小节中有详细阐述。

必应导出的单词本

<?xml version="1.0"?> <FCVocaPhraseList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Phrases> <Phrase> <Eng>descendant</Eng> <Phonetic>[d?'send?nt] </Phonetic> <Defi>n. 后裔;后代;子孙;(由过去类似物发展来的)派生物 adj. 同“descendent”; web. 弟子;子代;后嗣</Defi> <Date>2014-05-16 17:08:18</Date> <Note /> </Phrase> <Phrase> <Eng>strive</Eng> <Phonetic>[stra?v]</Phonetic> <Defi>v. 努力;奋斗;力求;力争;</Defi> <Date>2014-05-09 11:09:55</Date> <Note /> </Phrase> </Phrases> </FCVocaPhraseList>

Model类

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.Serialization; using System.Xml.Serialization; using System.Xml; using System.Xml.Schema; using System.ServiceModel; namespace ConsoleApplication3 { [DataContract(Name = "FCVocaPhraseList")] [KnownType(typeof(FCVocaPhraseList))] public class FCVocaPhraseList { [DataMember(Name = "Phrases")] public Phrases Phrases { get; set; } } [CollectionDataContract(ItemName = "Phrase")] public class Phrases : List<Phrase> { } [DataContract(Name = "Phrase")] public class Phrase { [DataMember (Order = 0),XmlElement] public string Eng { get; set; } [DataMember(Order = 1), XmlElement] public string Phonetic { get; set; } [DataMember(Order = 2), XmlElement] public string Defi { get; set; } [DataMember(Order = 3), XmlElement] public string Date { get; set; } [DataMember(Order = 4), XmlElement] public string Note { get; set; } } }

处理程序

using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; using System.IO; using System.Xml; using System.Xml.Linq; using System.Xml.Serialization; using System.Collections.ObjectModel; namespace ConsoleApplication3 { class Program { static void Main(string[] args) { FCVocaPhraseList plist = ReadImportedBingDictXml(@"C:\Users\v-applwu\Desktop\ToDo\我的生词本20140516.xml"); WriteToApplicationXml(plist); FCVocaPhraseList plist2 = ReadApplicationXml(@"111111.xml"); Console.WriteLine(plist2.Phrases.Count); } static FCVocaPhraseList ReadImportedBingDictXml(string ImportedDictFile) { List<Phrase> phrases = XElement.Load(ImportedDictFile).Descendants("Phrase").Select( p => new Phrase() { Eng = p.Element("Eng").Value, Phonetic = p.Element("Phonetic").Value, Defi = p.Element("Defi").Value, Note = p.Element("Note").Value, Date = p.Element("Date").Value }).ToList(); ObservableCollection<Phrase> observableCollection = new ObservableCollection<Phrase>(); phrases.ForEach(x => observableCollection.Add(x)); FCVocaPhraseList pList = new FCVocaPhraseList(); pList.Phrases = new Phrases() { }; pList.Phrases.AddRange(phrases); return pList; } static void WriteToApplicationXml(FCVocaPhraseList pList) { DataContractSerializer serializer = new DataContractSerializer(typeof(FCVocaPhraseList)); using (FileStream writer = new FileStream(@"111111.xml", FileMode.OpenOrCreate)) { serializer.WriteObject(writer, pList); } } static FCVocaPhraseList ReadApplicationXml(string xmlName) { DataContractSerializer serializer = new DataContractSerializer(typeof(FCVocaPhraseList)); FCVocaPhraseList guyToRead = null; using (FileStream inputStream = new FileStream(xmlName, FileMode.Open)) using (XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(inputStream, new XmlDictionaryReaderQuotas())) { guyToRead = serializer.ReadObject(reader, true) as FCVocaPhraseList; } return guyToRead; } } }
486°/4868 人阅读/0 条评论 发表评论

登录 后发表评论