最新公司项目中有部份需要使用WCF进行开发,抽空预研和学习了一下WCF的应用。同时也作好笔记,以备忘。
WCF中比较重要的部份契约,即我们通常所说的对外接口,有WEBSERVICE经验的朋友都知道,这就是所谓的服务器接。只不过在WCF中用契约来对其进行称呼。
其中契约包括:服务契约(通常说的功能接口)、数据契约(比如类库类型,枚举,实体类对象,序列等)、消息契约、错误契约
服务契约:
使用[ServiceContract] 来进行声明限定。通常在接口或类的前面声明。
该契约支持的属性如下:
写法举例:
[ServiceContract(Name = "HeatingManagerService",
Namespace= "http://www.cnblogs.com/fengsh998")]
public interface IHeatingManagerBase { ....... }服务契约中还需要对每个对外暴露的方法进行操作限制声明。
使用:[OperationContract]
其支持的属性如下:
eg:
[OperationContract(Name = "Add", Action = "http://www.cnblogs.com/fengsh998/Add", ReplyAction = "http://www.cnblogs.com/fengsh998/AddResponse")]
int add(int x, int y);
数据契约:
使用 [DataContract]进行限制
支持的属性如下:
如:
[DataContract][Flags] public enum VersionType { [EnumMember]kVTNone = 1, //不需要更新 [EnumMember]kVTCanUpdate = 2, //可以选择更新 [EnumMember]kVTMustUpdate = 4, //强制更新 }数据契约中还有对数据成员的声明[EnumMember] 枚举,[DataMember]类成员
[DataMember(Name = "AreaId", IsRequired = false, Order = 0)]
public Guid AreaId{ get; set; }
[DataMember(Name = "Id", IsRequired = false, Order = 1)]
public Guid Id{ get; set; }
ServiceKnownType
属性:
eg:
[DataContract][Flags] public enum VersionType { [EnumMember]kVTNone = 1, //不需要更新 [EnumMember]kVTCanUpdate = 2, //可以选择更新 [EnumMember]kVTMustUpdate = 4, //强制更新 } [ServiceKnownType(typeof(VersionType))] //声明服务契约的名称最好是描述出服务的业务名来命名 [ServiceContract(Name = "IntfService", Namespace = "http://www.xxxproject.com/")] public interface IFuncInterface{...}
消息契约(MessageContract)
• MessageContractAttribute
– 对控制消息头和消息体元素提供了强力支持
• 所支持的属性:
– MessageHeaderAttribute
– MessageBodyMemberAttribute
– 凡是有[MessageHeader]或[MessageBody]的那些属性,它们就是在客户端调用服务相应方法的参数。
• 用于:
– 添加自定义头(custom headers)
– 控制消息是否被包装
– 控制签名与加密 [MessageContract]:
• 将一个类型转换为SOAP消息
– 类型可以包含消息头和消息体的元素
• 能够设置IsWrapped, ProtectionLevel
• 可以设置显式Name, Namespace
如下面的代码:
[MessageContract(IsWrapped=true, ProtectionLevel=ProtectionLevel.Sign)]
public class SaveLinkRequest {…}
[MessageContract] public class SaveLinkResponse {…}
[MessageHeader]:
• 应用到消息契约的域(fields)或者( properties)
– 为创建自定义头提供了简单的方法
• 能够提供Name, Namespace, ProtectionLevel
• 可以设置SOAP协议的设置:Relay, Actor,MustUnderstand
[MessageBody]:
• 应用到消息契约的域(fields)或者属性(properties)
• 能够拥有多个body元素
– 等价于在操作中拥有多个参数
– 返回多个复杂类型数据的唯一方法
• 总是提供顺序(Order)
• 可以设置Name, Namespace, ProtectionLevel
1: [ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
2: public interface IService2
3: {
4: [OperationContract]
5: SaveResponse SaveItem(SaveRequest requestMessage);
6: [OperationContract]
7: GetResponse GetItem(GetRequest requestMessage);
8: }
9:
10: public class Service2 : IService2
11: {
12: private UserInfoEntity _item;
13:
14: public SaveResponse SaveItem(SaveRequest requestMessage)
15: {
16: this._item = requestMessage.Item;
17: return new SaveResponse();
18: }
19:
20: public GetResponse GetItem(GetRequest requestMessage)
21: {
22: if (requestMessage.LicenseKey != "lmg")
23: {
24: throw new FaultException("Invalid license key.");
25: }
26: _item.Id = "001";
27: _item.Name = "lmg";
28: _item.Sex = SexType.boy;
29:
30: return new GetResponse(_item);
31: }
32: }
33:
34: #region 消息契约
35: [MessageContract(IsWrapped = true, ProtectionLevel = ProtectionLevel.EncryptAndSign)]
36: public class SaveRequest
37: {
38: [MessageBodyMember]
39: public UserInfoEntity Item { get; set; }
40: }
41:
42: [MessageContract(IsWrapped = false)]
43: public class SaveResponse
44: {
45: }
46:
47: [MessageContract(IsWrapped = false)]
48: public class GetRequest
49: {
50: [MessageHeader]
51: public string LicenseKey { get; set; }
52: }
53:
54: [MessageContract(IsWrapped = false)]
55: public class GetResponse
56: {
57: public GetResponse()
58: {
59: }
60:
61: public GetResponse(UserInfoEntity item)
62: {
63: this.Item = item;
64: }
65:
66: [MessageBodyMember]
67: public UserInfoEntity Item { get; set; }
68: }
69: #endregion
70:
消息契约注意:
配置文件注意的地方 权限应为 Message