WCF DataContract标记去除方式解析
创始人
2024-06-23 09:51:20
0

WCF是一个基于.Net Framework 2.0基础的由微软公司研发的开发插件,它的实际应用可以帮助编程人员轻松实现特定的功能需求。在这里我们将会介绍一种应用技巧,就是如何在使用中省略掉WCF DataContract标记。#t#

写过WCF程序的朋友都知道,在对实体对象在WCF和客户端之间传递时一定要加WCF DataContract标记这个类并用DataMember来标记要序列化的属性/字段。这一直正确,只是在.NET Framework 3.5 SP1中新添加了一些支持,那就是你不一定必须对这些实体对象应用DataContract标记,这被称作对plain old C# objects(POCO)的序列化支持。

 

Serializable标记大家都很熟悉,它是XmlSerializer的标记,在WCF中其实很少用这个标记,因为我们WCF用的是DataContractSerializer,对应的标记也是DataContract。但对于SP1来说,Serializable也以XmlSerializer的规则被正常解析,其对应的Mapping规则和Serializer对应,其公有可读写字段被默认序列化。当然,你也可以通过XmlElement等标记来做高级映射,但这不是我们这里需要谈及的内容。

 

WCF DataContract标记对应的序列化处理叫做DataContactSerializer。在WCF中一旦一个类被标记为DataContract,那么只有标记为DataMember的字段/属性才会被序列化。但如果你使用DataContract标记,那么DataContractSerializer默认将所有公有可读写字段序列化(这和Serializable是一样的)。假设我们有这么一个类:

 

  1. public class Person  
  2. {  
  3. public Person()  
  4. { }  
  5. public Person(string strId, string strName)  
  6. {  
  7. this.Id = strId;  
  8. this.Name = strName;  
  9. }  
  10. private string strid;  
  11. public string Id { get { return strid; } set { strid = value; } }  
  12. public string Name;  
  13. public Person Spouse;  
  14. private int Number = 343;  

 

 

对于DataSerializer来说,他和给所有公有属性添加DataMember并将类标记为WCF DataContract标记是一样的。下面的一段程序分别将一个Person的实例对象分别用XmlSerializer和DataContractSerializer来序列化:

 

  1. static void Main(string[] args)  
  2. {  
  3. Person p = new Person();  
  4. p.Id = "123";  
  5. p.Name = "Aaron";  
  6. p.Spouse = new Person();  
  7. p.Spouse.Id = "456";  
  8. p.Spouse.Name = "Monica";  
  9. DataContractSerializer dcs = new 
    DataContractSerializer(typeof(Person));  
  10. using (FileStream fs = new FileStream("person.xml", 
    FileMode.Create))  
  11. {  
  12. dcs.WriteObject(fs, p);  
  13. }  
  14. XmlSerializer xs = new XmlSerializer(typeof(Person));  
  15. using (FileStream fs = new FileStream("person_serialization.xml",
     FileMode.Create))  
  16. {  
  17. xs.Serialize(fs, p);  
  18. }  

 

对于序列化后的内容我们得到的结果其实是一样的:仅有公有属性/字段被序列化

 

  1. < Person xmlns="http://schemas.datacontract.org/2004/07/
    Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
  2. < Id>123< /Id> 
  3. < Name>Aaron< /Name> 
  4. < Spouse> 
  5. < Id>456< /Id> 
  6. < Name>Monica< /Name> 
  7. < Spouse i:nil="true"/> 
  8. < /Spouse> 
  9. < /Person> 

 

但如果你使用了DataContract来标记这个类,却没有使用DataMember,那么没有任何属性/字段被序列化:

 

  1. [DataContract]  
  2. public class Person  
  3. {  
  4. private string strid;  
  5. public string Id { get { return strid; } set { strid = value; } }  
  6. public string Name;  
  7. public Person Spouse;  
  8. private int Number = 343;  
  9. }  
  10. < Person xmlns="http://schemas.datacontract.org/2004/07/
    Serialization" xmlns:i=http://www.w3.org/2001/XMLSchema-instance /> 

 

 

对于将类标记成Serializable,DataContractSerializer的序列化可能让我们觉得有些奇怪,它本质上是将所有可读写字段序列化,这其中还包括私有字段。例如我们将Person类用[Serializable]标记,执行程序,我们会得到以下的结果:

 

  1. < Person xmlns="http://schemas.datacontract.org/2004/07
    /Serialization" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
  2. < Name>Aaron< /Name> 
  3. < Number>0< /Number> 
  4. < Spouse> 
  5. < Name>Monica< /Name> 
  6. < Number>0< /Number> 
  7. < Spouse i:nil="true"/> 
  8. < _id>456< /_id> 
  9. < /Spouse> 
  10. < _id>123< /_id> 
  11. < /Person> 

 

一个简单的WCF程序来看看来检验一下是否正确。在Contract生命中我们并不需要制定任何的标记,并声明一个得到DeskMesh的方法:

 

  1. [ServiceContract]  
  2. public interface IDeskMesh  
  3. {  
  4. [OperationContract]  
  5. DeskMesh GetDeskMesh(string name);  
  6. }  
  7. public class DeskMesh  
  8. {  
  9. private int _id;  
  10. private int Number = 4433;  
  11. public int ID  
  12. {  
  13. get { return _id; }  
  14. set { _id = value; }  
  15. }  
  16. public string Name { get; set; }  
  17. public string Description { get; set; }  
  18. public string Unit { get; set; }  
  19. public float Price { get; set; }  
  20. public DateTime Created { get; set; }  
  21. public override string ToString()  
  22. {  
  23. return string.Format("ID:{4}"r"nName: {0}"r"nUnit:{1}"r"
    nPrice:{2}"r"nCreated:{3}"r"nNumber:{5}",  
  24. Name, Unit, Price, Created.ToShortDateString(),
    ID.ToString(),Number.ToString());  
  25. }  

 

 

客户端调用,会返回一个DeskMesh的实例。通过结果,你会发现这完全和你标记WCF DataContract标记的实体在WCF两端传递一模一样。

 

  1. void Main(string[] args)  
  2. {  
  3. Console.WriteLine("Requesting...");  
  4. ServiceClient client = new ServiceClient();  
  5. DeskMesh mesh = client.GetDeskMesh("");  
  6. Console.WriteLine(mesh.ToString());  
  7. Console.WriteLine("press any key to continue...");  
  8. Console.Read();  

 

 

总结一下吧,WCF中应用各个标记时所作的序列化处理:

1. 不给任何标记将会做XML映射,所有公有属性/字段都会被序列化

2. [Serializable]标记会将所有可读写字段序列化

3. [DataContract]和[DataMember]联合使用来标记被序列化的字段

以上就是对WCF DataContract标记的相关介绍。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...