WCF學習筆記(三),數據契約

 WCF能夠託管CLR類型,客戶端能傳遞和處理CLR類型的數據(如:string和int),但是如果我們自己定義的類型(如:聲明的Customer類)。其實WCF的傳遞CLR自己類型時,是因爲已經把它序列化成了xml信息集,而我們自己定義的類型則需要自己去顯示的聲明序列化。

序列化
    .net的序列化。.net是通過反射機制自動實現對象的序列化與反序列化。首先.net能夠捕獲對象每個字段的值,然後進行序列化,反序列化時,.net創建一個對應類型的新的對象,讀取持久化的值,然後設置字段的值。.net對象狀態的序列化到Stream中。
    我們自定義的類或者結構是不支持序列化的,因此如果我們的類是否要序列化是需要類的開發者來指定的。如果需要支持序列化的話,我們可以在類或者結構上添加Serializable屬性。
    如:
    [Serializable]
    public class Customer
    {
        ...
    }
    但是如果添加了Serializable就要求類型的成員也要支持序列化的,不然會拋出異常,但是我們可以通過在成員上添加NonSerizlized屬性來說明這個成員不需要序列化。

格式
    .net爲序列化和反序列化提供了兩種格式器:
            1.BinaruFormatter:將類型序列化爲二進制格式。
            2.SoapFormatter:格式成SOAP特定的XML格式。
    但是這兩者都要將類型的程序集以及版本控制信息持久化到Stream中,而面向服務要求參與者都能擁有類型程序集,所以如果用這兩種格式就必須要去共享Stream,這樣肯定不是我們理想的。從而有了WCF格式器。
    
    WCF的格式器:DataContractSerializer,是能夠共享數據契約的。WCF數據進行序列化時,WCF一般會自己調用DataContractSerializer來序列的,不需要我們去指定的。同時我們也可以用DataContractSerializer進行Stream的序列化。

數據契約特性
    Serializable要求類型的所有的成員都是可以序列化的,而且不支持類型名跟成員名的別名,這樣我們就沒法明確指定哪些成員是要放到數據契約中的。然而WCF數據契約特性DataContract很好的解決了這些問題。
    DataContract Attribute 是在命名空間System.Runtime.Serialization中的,是可以在Enum、Struct、Class上標識的。擁有成員Name,Namespace。而當我們在一個class或者struct上使用時,wcf是不會序列化類型的成員的。如:
        [DataContract]
        public class Emloyee
        {
            public string _firstName;
            public string _lastName;
        }
Employee裏面的成員_firstName,_lastName是不會去序列化的,所以我們還必須去顯示的指定需要序列化的成員。
    DataMember Attribute是用來指定需要序列化類型的成員。DataMember的成員:
        IsRequried:序列化時是否必須要賦值;
        Name:指定成員的別名;
        Order:指定序列化後的排列位置。
我們看一個例子Customer.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;

namespace HenllyeeDataContract
{
    [DataContract(Name
="Customer",Namespace="HenllyeeDataContract")]
    
public class Customer
    
{
        
Fileds
        
        
Attributes
    }

}

 上面我們定義了一個數據契約,將DataMember屬性定義在幾個屬性上(建議定義在屬性上,不要定義在字段上)。

服務契約爲:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace HenllyeeServiceContract
{
    [ServiceContract(Name
="CustomerManagerService",Namespace="www.systhinker.com,專注、技術、共享2008/06/29")]
    
public interface ICustomerManager
    
{
        
/// 
        
/// Save customer's info
        
/// 
        
/// the customer's object

        [OperationContract(Name="SaveCustomerInfo",Action="www.systhinker.com,專注、技術、共享2008/06/29/CustomerManagerService/SaveCustomer",
            ReplyAction 
= "www.systhinker.com,專注、技術、共享2008/06/29/CustomerManagerService/SaveCustomerResponse")]
        
void SaveCustomer(HenllyeeDataContract.Customer customer);

        
/// 
        
/// Get customer's info
        
/// 
        
/// a customer

        [OperationContract(Name = "GetCustomerInfo", Action = "www.systhinker.com,專注、技術、共享2008/06/29/CustomerManagerService/GetCustomer",
            ReplyAction 
= "www.systhinker.com,專注、技術、共享2008/06/29/CustomerManagerService/GetCustomerResponse")]
        HenllyeeDataContract.Customer GetCustomer();
    }

}

服務契約裏面具體實現:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace HenllyeeServiceContract
{
    [ServiceBehavior(InstanceContextMode 
= InstanceContextMode.Single)]
    
public class CustomerManager:ICustomerManager
    
{
        
fileds

        
Members
    }

}



主機的實現就不在次給出了。
然後我們在客戶端添加服務引用,即可以了。我們在客戶端可以看到導入的數據契約:

    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.CodeDom.Compiler.GeneratedCodeAttribute(
"System.Runtime.Serialization""3.0.0.0")]
    [System.Runtime.Serialization.DataContractAttribute(Name
="Customer", Namespace="HenllyeeDataContract")]
    [System.SerializableAttribute()]
&
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章