zoukankan      html  css  js  c++  java
  • 数据契约(DataContract)

    服务契约定义了远程访问对象和可供调用的方法,数据契约则是服务端和客户端之间要传送的自定义数据类型。

    一旦声明一个类型为DataContract,那么该类型就可以被序列化在服务端和客户端之间传送,如下所示。

          [DataContract]

         public class UserInfo

         {

              //….

    }

    只有声明为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,头的内容被接收到以后会在响应消息中回发给消息发送端。

  • 相关阅读:
    面向接口程序设计思想实践
    Block Chain Learning Notes
    ECMAScript 6.0
    Etcd Learning Notes
    Travis CI Build Continuous Integration
    Markdown Learning Notes
    SPRING MICROSERVICES IN ACTION
    Java Interview Questions Summary
    Node.js Learning Notes
    Apache Thrift Learning Notes
  • 原文地址:https://www.cnblogs.com/DebugMe/p/2646383.html
Copyright © 2011-2022 走看看