WCF中的Contracts
WCF通过Contract来说明服务和操作,一般包含五种类型的Contract:ServiceContract,OperationContract,FaultContract,DataContract,MessageContract。
1.ServiceContract
ServiceContract向外部暴漏了可以提供的服务接口,它可以包含服务名称、命名空间等服务器端的配置信息。
1: [ServiceContract]2: interface IMyContract
3: { 4: [OperationContract]5: string MyMethod();
6: } 7: 8: class MyService : IMyContract
9: {10: public string MyMethod()
11: {12: return "Hello World";
13: } 14: }2.OperationContract
OperationContract定义在ServiceContract的内部,定义了具体的服务操作。在此基础上,可以对操作的事务,绑定(One-way,Two-way等)和FaultContract信息。
1: [ServiceContract]2: interface IMyContract
3: {4: [FaultContract(typeof(MyFaultContract))]
5: [OperationContract]6: string MyMethod();
7: }3.Data Contract
定义了服务器和客户端交互的内容,它可以标识类,以便作为OperationContract的参数或者返回类型。
1: [DataContract]2: class Person
3: { 4: [DataMember]5: public string ID;
6: [DataMember]7: public string Name;
8: } 9: 10: [ServiceContract]11: interface IMyContract
12: { 13: [OperationContract]14: Person GetPerson(int ID);
15: }4.MessageContract
当OperationContract需要传递参数或者返回值时,可以使用MessageContract。它可以定义消息的Header和Body,以及安全性等。
1: [ServiceContract]2: public interface IRentalService
3: { 4: [OperationContract]5: double CalPrice(PriceCalculate request);
6: } 7: 8: [MessageContract]9: public class PriceCalculate
10: { 11: [MessageHeader]12: public MyHeader SoapHeader { get; set; }
13: [MessageBodyMember]14: public PriceCal PriceCalculation { get; set; }
15: } 16: 17: [DataContract]18: public class MyHeader
19: { 20: [DataMember]21: public string UserID { get; set; }
22: } 23: 24: [DataContract]25: public class PriceCal
26: { 27: [DataMember]28: public DateTime PickupDateTime { get; set; }
29: [DataMember]30: public DateTime ReturnDateTime { get; set; }
31: [DataMember]32: public string PickupLocation { get; set; }
33: [DataMember]34: public string ReturnLocation { get; set; }
35: } 36: 5.FaultContract
FaultContract定义了服务可能出现的异常信息,以及服务队错误的处理和错误信息抛出到客户端的内容。一个OperationContact可以包含0个或多个FaultContract。
1: [ServiceContract]2: interface IMyContract
3: {4: [FaultContract(typeof(MyFaultContract1))]
5: [FaultContract(typeof(MyFaultContract2))]
6: [OperationContract]7: string MyMethod();
8: 9: [OperationContract]10: string MyShow();
11: }MessageContract和DataContract的比较
区别
DataContract提供了一种将.net的CLR类型映射为可以被其他应用程序识别的基于W3C的Xml的方法,使得不同的应用间无须考虑对应使用的是什么类型的数据,而只需关注这些被抽象的Xml信息。
MessageContract则描述了SOAP消息的结构,最终在服务器和客户端进行传递,因此能够对SOAP信息的Header和Bodies进行直接的访问和处理,可以对复杂的类型进行处理。
为什么需要或者什么时候使用MessageContract
MessageContract一般只在你需要对消息体进行直接控制的时候使用,例如添加特定的Header,Footer等信息。在一些场合,如果需要在消息中包含Session相关的信息时,通过Header进行传递,则无需像消息体中增加额外的参数。或者有时你需要提供一个自定义的安全协议或者在应用间传递身份令牌。
当然,使用MessageContract时需要从SOAP Header中检索信息,而不是直接序列化后进行处理。
不要混用MessageContract和DataContract
对于一个OperationContract来说,不要在参数和返回值中分别使用MessageContract和DataContract,否则在生成WSDL时会引起运行时错误。