WCF DataContract標(biāo)記去除方式解析
WCF是一個(gè)基于.Net Framework 2.0基礎(chǔ)的由微軟公司研發(fā)的開(kāi)發(fā)插件,它的實(shí)際應(yīng)用可以幫助編程人員輕松實(shí)現(xiàn)特定的功能需求。在這里我們將會(huì)介紹一種應(yīng)用技巧,就是如何在使用中省略掉WCF DataContract標(biāo)記。#t#
寫(xiě)過(guò)WCF程序的朋友都知道,在對(duì)實(shí)體對(duì)象在WCF和客戶(hù)端之間傳遞時(shí)一定要加WCF DataContract標(biāo)記這個(gè)類(lèi)并用DataMember來(lái)標(biāo)記要序列化的屬性/字段。這一直正確,只是在.NET Framework 3.5 SP1中新添加了一些支持,那就是你不一定必須對(duì)這些實(shí)體對(duì)象應(yīng)用DataContract標(biāo)記,這被稱(chēng)作對(duì)plain old C# objects(POCO)的序列化支持。
Serializable標(biāo)記大家都很熟悉,它是XmlSerializer的標(biāo)記,在WCF中其實(shí)很少用這個(gè)標(biāo)記,因?yàn)槲覀僕CF用的是DataContractSerializer,對(duì)應(yīng)的標(biāo)記也是DataContract。但對(duì)于SP1來(lái)說(shuō),Serializable也以XmlSerializer的規(guī)則被正常解析,其對(duì)應(yīng)的Mapping規(guī)則和Serializer對(duì)應(yīng),其公有可讀寫(xiě)字段被默認(rèn)序列化。當(dāng)然,你也可以通過(guò)XmlElement等標(biāo)記來(lái)做高級(jí)映射,但這不是我們這里需要談及的內(nèi)容。
WCF DataContract標(biāo)記對(duì)應(yīng)的序列化處理叫做DataContactSerializer。在WCF中一旦一個(gè)類(lèi)被標(biāo)記為DataContract,那么只有標(biāo)記為DataMember的字段/屬性才會(huì)被序列化。但如果你使用DataContract標(biāo)記,那么DataContractSerializer默認(rèn)將所有公有可讀寫(xiě)字段序列化(這和Serializable是一樣的)。假設(shè)我們有這么一個(gè)類(lèi):
- public class Person
- {
- public Person()
- { }
- public Person(string strId, string strName)
- {
- this.Id = strId;
- this.Name = strName;
- }
- private string strid;
- public string Id { get { return strid; } set { strid = value; } }
- public string Name;
- public Person Spouse;
- private int Number = 343;
- }
對(duì)于DataSerializer來(lái)說(shuō),他和給所有公有屬性添加DataMember并將類(lèi)標(biāo)記為WCF DataContract標(biāo)記是一樣的。下面的一段程序分別將一個(gè)Person的實(shí)例對(duì)象分別用XmlSerializer和DataContractSerializer來(lái)序列化:
- static void Main(string[] args)
- {
- Person p = new Person();
- p.Id = "123";
- p.Name = "Aaron";
- p.Spouse = new Person();
- p.Spouse.Id = "456";
- p.Spouse.Name = "Monica";
- DataContractSerializer dcs = new
DataContractSerializer(typeof(Person));- using (FileStream fs = new FileStream("person.xml",
FileMode.Create))- {
- dcs.WriteObject(fs, p);
- }
- XmlSerializer xs = new XmlSerializer(typeof(Person));
- using (FileStream fs = new FileStream("person_serialization.xml",
FileMode.Create))- {
- xs.Serialize(fs, p);
- }
- }
對(duì)于序列化后的內(nèi)容我們得到的結(jié)果其實(shí)是一樣的:僅有公有屬性/字段被序列化
- < Person xmlns="http://schemas.datacontract.org/2004/07/
Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">- < Id>123< /Id>
- < Name>Aaron< /Name>
- < Spouse>
- < Id>456< /Id>
- < Name>Monica< /Name>
- < Spouse i:nil="true"/>
- < /Spouse>
- < /Person>
但如果你使用了DataContract來(lái)標(biāo)記這個(gè)類(lèi),卻沒(méi)有使用DataMember,那么沒(méi)有任何屬性/字段被序列化:
- [DataContract]
- public class Person
- {
- private string strid;
- public string Id { get { return strid; } set { strid = value; } }
- public string Name;
- public Person Spouse;
- private int Number = 343;
- }
- < Person xmlns="http://schemas.datacontract.org/2004/07/
Serialization" xmlns:i=http://www.w3.org/2001/XMLSchema-instance />
對(duì)于將類(lèi)標(biāo)記成Serializable,DataContractSerializer的序列化可能讓我們覺(jué)得有些奇怪,它本質(zhì)上是將所有可讀寫(xiě)字段序列化,這其中還包括私有字段。例如我們將Person類(lèi)用[Serializable]標(biāo)記,執(zhí)行程序,我們會(huì)得到以下的結(jié)果:
- < Person xmlns="http://schemas.datacontract.org/2004/07
/Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">- < Name>Aaron< /Name>
- < Number>0< /Number>
- < Spouse>
- < Name>Monica< /Name>
- < Number>0< /Number>
- < Spouse i:nil="true"/>
- < _id>456< /_id>
- < /Spouse>
- < _id>123< /_id>
- < /Person>
一個(gè)簡(jiǎn)單的WCF程序來(lái)看看來(lái)檢驗(yàn)一下是否正確。在Contract生命中我們并不需要制定任何的標(biāo)記,并聲明一個(gè)得到DeskMesh的方法:
- [ServiceContract]
- public interface IDeskMesh
- {
- [OperationContract]
- DeskMesh GetDeskMesh(string name);
- }
- public class DeskMesh
- {
- private int _id;
- private int Number = 4433;
- public int ID
- {
- get { return _id; }
- set { _id = value; }
- }
- public string Name { get; set; }
- public string Description { get; set; }
- public string Unit { get; set; }
- public float Price { get; set; }
- public DateTime Created { get; set; }
- public override string ToString()
- {
- return string.Format("ID:{4}"r"nName: {0}"r"nUnit:{1}"r"
nPrice:{2}"r"nCreated:{3}"r"nNumber:{5}",- Name, Unit, Price, Created.ToShortDateString(),
ID.ToString(),Number.ToString());- }
- }
客戶(hù)端調(diào)用,會(huì)返回一個(gè)DeskMesh的實(shí)例。通過(guò)結(jié)果,你會(huì)發(fā)現(xiàn)這完全和你標(biāo)記WCF DataContract標(biāo)記的實(shí)體在WCF兩端傳遞一模一樣。
- void Main(string[] args)
- {
- Console.WriteLine("Requesting...");
- ServiceClient client = new ServiceClient();
- DeskMesh mesh = client.GetDeskMesh("");
- Console.WriteLine(mesh.ToString());
- Console.WriteLine("press any key to continue...");
- Console.Read();
- }
總結(jié)一下吧,WCF中應(yīng)用各個(gè)標(biāo)記時(shí)所作的序列化處理:
1. 不給任何標(biāo)記將會(huì)做XML映射,所有公有屬性/字段都會(huì)被序列化
2. [Serializable]標(biāo)記會(huì)將所有可讀寫(xiě)字段序列化
3. [DataContract]和[DataMember]聯(lián)合使用來(lái)標(biāo)記被序列化的字段
以上就是對(duì)WCF DataContract標(biāo)記的相關(guān)介紹。