数据契约(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,头的内容被接收到以后会在响应消息中回发给消息发送端。

例如:

string html="{"Table":[{"IssueNum":"20130725023","Result":"0 3 7 9 1","AwardTime":"2013-07-25 01:55"},{"IssueNum":"20130725022","Result":"0 1 3 8 9","AwardTime":"2013-07-25 01:50"},{"IssueNum":"20130725021","Result":"9 4 5 5 0","AwardTime":"2013-07-25 01:45"},{"IssueNum":"20130725020","Result":"2 5 6 1 5","AwardTime":"2013-07-25 01:40"},{"IssueNum":"20130725019","Result":"1 5 2 6 8","AwardTime":"2013-07-25 01:35"},{"IssueNum":"20130725018","Result":"5 3 2 3 9","AwardTime":"2013-07-25 01:30"},{"IssueNum":"20130725017","Result":"9 3 6 7 4","AwardTime":"2013-07-25 01:25"},{"IssueNum":"20130725016","Result":"5 7 5 2 8","AwardTime":"2013-07-25 01:20"},{"IssueNum":"20130725015","Result":"2 7 0 3 9","AwardTime":"2013-07-25 01:15"},{"IssueNum":"20130725014","Result":"4 5 2 0 6","AwardTime":"2013-07-25 01:10"},{"IssueNum":"20130725013","Result":"8 7 7 5 7","AwardTime":"2013-07-25 01:05"},{"IssueNum":"20130725012","Result":"2 4 2 6 5","AwardTime":"2013-07-25 01:00"},{"IssueNum":"20130725011","Result":"9 6 4 8 8","AwardTime":"2013-07-25 00:55"},{"IssueNum":"20130725010","Result":"5 3 3 4 5","AwardTime":"2013-07-25 00:50"},{"IssueNum":"20130725009","Result":"3 8 3 1 3","AwardTime":"2013-07-25 00:45"},{"IssueNum":"20130725008","Result":"5 6 8 7 8","AwardTime":"2013-07-25 00:40"},{"IssueNum":"20130725007","Result":"8 1 3 7 9","AwardTime":"2013-07-25 00:35"},{"IssueNum":"20130725006","Result":"6 2 4 8 4","AwardTime":"2013-07-25 00:30"},{"IssueNum":"20130725005","Result":"3 4 3 9 5","AwardTime":"2013-07-25 00:25"},{"IssueNum":"20130725004","Result":"8 5 5 8 0","AwardTime":"2013-07-25 00:20"},{"IssueNum":"20130725003","Result":"9 4 4 2 9","AwardTime":"2013-07-25 00:15"},{"IssueNum":"20130725002","Result":"3 6 1 2 0","AwardTime":"2013-07-25 00:10"},{"IssueNum":"20130725001","Res
ult":"5 6 0 2 4","AwardTime":"2013-07-25 00:05"}]}"

//
 public static string GetJson(string html)
 {
            SSCSerialize ssc = new SSCSerialize(); //实体类名
            var json = ConvertJson(html,ssc.GetType()); // 解析JSON
            return json.ToString();
 }

//解析JSON
private static object ConvertJson(string json,Type t)
 {
            try
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(t);
                using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
                {
                    return serializer.ReadObject(ms);
                    
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
}

//实体类
[DataContract]
 public class SSCSerialize
{
        [DataMember]
        public string IssueNum { get; set; }
        [DataMember]
        public string Result { get; set; }
        [DataMember]
        public string AwardTime { get; set; }
 }

解析出来是FromData.IEnumerable.SSCSerialize类名.

原文地址:https://www.cnblogs.com/wlming/p/5132820.html