Attribute

在c#中,“[...]”这个叫做Attribute,一般翻译为“特性”


特性是一个继承自System.Attribute类的类,其实特性和注释(即“/* ... */”)类似,是用于描述程序集、类型、成员的“备注信息”,和注释不同的是:注释是给“人”看的,而特性是给“编译器”看的,
举例来说:
[ServiceContract] 这个特性告诉编译器,该类型(指IInterface1)是一个服务契约,
[OperationContract] 这个特性告诉编译器,该成员(指Function1)是一个操作契约,
[DataContract] 该成员是数据契约
[FaultContract(typeof(Exception))] 错误契约,FaultContract特性支持重复配置,可以在单个操作中列出多个错误契约

这样在编程的时候,用反射机制可以判断出,哪些类型标记过服务契约,哪些成员标记过操作契约,在WCF中会找到这些做服务。

只有声明为DataContract的类型的对象可以被传送,且只有成员属性会被传递,成员方法不会被传递。WCF对声明为DataContract的类型提供更加细节的控制,可以把一个成员排除在序列化范围以外,也就是说,客户端程序不会获得被排除在外的成员的任何信息,包括定义和数据。默认情况下,所有的成员属性都被排除在外,因此需要把每一个要传送的成员声明为DataMember,如下所示。


    [DataContract]
    public class UserInfo
    {
        [DataMember]
        public string UserName
        {
            get;
            set;
        }
        [DataMember]
        public int Age
        {
            get;
            set;
        }
        [DataMember]
        public string Location
        {
            get;
            set;
        }
        public string Zodiac
        {
            get;
            set;
        }
}
上面这段代码把UserInfo类声明为DataContract,将UserName、Age、Location这3个属性声明为DataMember(数据成员)。Zodiac成员没有被声明为DataMember,因此在交换数据时,不会传输Zodiac的任何信息。


DataContract也支持Name/Namespace属性,如同ServiceContract,Name和Namespace可以自定义名称和命名空间,客户端将使用自定义的名称和命名空间对DataContract类型进行访问。


声明为DataMember的成员也可以自定义客户端可见的名称,例如:


[DataMember(Name="Name")]
public string UserName
{
     get;
     set;
}
[DataMember(Name="Age")]
public int UserAge
{
          get;
          set;
}
除了Name和Namespace以外,DataMember还有以下参数,它们的含义分别如下。




(1)IsRequired:值为true时,要求序列化引擎检查对象是否存在该值;若无,则会有异常抛出。
(2)Order:bool类型值,值为true时,序列化和反序列化过程将会按成员定义的顺序进行,这对依赖于成员位置的反序列化过程无比重要。
(3)EmitDefaultvalue:为成员属性设置一个默认值。


一般情况下,将类型声明为DataContract就可以满足传送的需求了,不过特殊情况是难以避免的,这时就需要对要传送的SOAP消息进行更加精确的控制,MessageContract可以满足这种需求。


把一个类型声明为MessageContract,意味着它可以被序列化为SOAP消息,可以声明类型的成员为SOAP消息的各个部分,如Header、Body等,如下所示。


    [MessageContract]
    public class UserMessage
    {
        private string user = String.Empty;
        private string authKey = String.Empty;
        [MessageBodyMember(
          Name = "UserName",
          Namespace = "http://www.wcf.com")]
        public string User
        {
            get { return user; }
            set { user = value; }
        }
        [MessageHeader(
          Name = "AuthKey",
          Namespace = "http://www.wcf.com",
          MustUnderstand = true
        )]
        public string AuthKey
        {
            get { return authKey; }
            set { this.authKey = value; }
        }
}
User成员被声明为MessageBody(消息体)的一个成员,AuthKey被声明为消息头(MessageHeader)的一个成员。这个类将可以生成如下的SOAP消息。
<s:Envelope>
    <s:Header>
        <a:Action s:mustUnderstand="1">http://UserMessage/Action</a:Action>
        <h:AuthKey s:mustUnderstand="1" xmlns:h="http://www.wcf.com">xxxx</h:AuthKey>
    </s:Header>
    <s:Body>
        <UserMessage xmlns="Microsoft.WCF.Documentation">
             <User xmlns="http://www.wcf.com">abcd</User>
       </UserMessage>
    </s:Body>   
</s:Envelope>

MessageHeader中,MustUnderstand参数表示读取该头的程序必须能够识别头的内容,否则不能继续处理。Name/Namespace的作用与前面的元素相同。另有Relay参数,若为true,头的内容被接收到以后会在响应消息中回发给消息发送端。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值