天天看點

消息(7)——WCF程式設計模型中控制消息(1)綁定,契約

WCF服務要通過終結點來進行通信,終結點三大構成元素:ABC,其中的B,binding是重中之重,它解決了在消息交換過程中的編碼,傳輸協定,安全等問題。

綁定是分層的,一個綁定對象對應一組有序的綁定元素的集合。每層的元素專門處理其中某領域内的事務,來負責終結點通信中的其中一方面。這裡給出綁定對象的綁定元素的層表:

選項 是否必需
事務流 TransactionFlowBindingElement
可靠性 ReliableSessionBindingElement
安全性 對稱、非對稱、傳輸級
形狀更改 CompositeDuplexBindingElement
傳輸更新 SSL 流、Windows 流、對等解析程式
編碼 文本、二進制、MTOM、自定義
傳輸 TCP、命名管道、HTTP、HTTPS、MSMQ、自定義

其中的編碼層和傳輸層是必須的。系統提供了足夠多的綁定類型:

綁定 互操作性 安全模式(預設) 會話(預設) 事務 雙工
BasicHttpBinding Basic Profile 1.1 (無)、傳輸、消息、混合 無、(無) (無) n/a
WSHttpBinding WS 無、傳輸、(消息)、混合 (無)、傳輸、可靠會話 (無)、是
WS2007HttpBinding WS-Security、WS-Trust、WS-SecureConversation、WS-SecurityPolicy
WSDualHttpBinding 無、(消息) (可靠會話)
WSFederationHttpBinding WS-Federation 無、(消息)、混合 (無)、可靠會話
WS2007FederationHttpBinding
NetTcpBinding .NET 無、(傳輸)、消息、混合 可靠對話、(傳輸)
NetNamedPipeBinding 無、(傳輸)
NetMsmqBinding 無、消息、(傳輸)、兩者
NetPeerTcpBinding 對等 無、消息、(傳輸)、混合
MsmqIntegrationBinding MSMQ

從這個表中可知:BasicHttpBinding類型隻有兩層綁定元素。

驗證一下:

public void TestBindingElements()

{

    BasicHttpBinding _binding = new BasicHttpBinding();

BindingElementCollection eles=

_binding.CreateBindingElements();

    foreach (BindingElement ele in eles)

Console.WriteLine(ele.ToString());

}

結果:

System.ServiceModel.Channels.TextMessageEncodingBindingElement

System.ServiceModel.Channels.HttpTransportBindingElement

因為每種綁定類型的綁定元素構成的不同,在應用中會有很大不同。例如基礎綁定類型:它不支援雙工通信,不支援事務和會話服務。

(一)  通過綁定對象的屬性進行消息的控制

綁定對象有多個屬性用于控制消息。例如基礎綁定:

·EnvelopeVersio:擷取此綁定處理的消息将要使用的 SOAP 版本。

·MessageEncoding:擷取或設定是使用 MTOM 還是文本對 SOAP 消息進行編碼。

·MessageVersion:擷取由綁定所配置的用戶端和服務使用的消息版本。

·Name:擷取或設定綁定的名稱。

·Namespace:擷取或設定綁定的 XML 命名空間。

·Security:擷取與此綁定一起使用的安全類型。

·TextEncoding:擷取或設定用于消息文本的字元編碼。

設定綁定的名字:Name。設定可以在配置檔案中配置也可以在自托管宿主程式中通過程式設定。

(二)  契約

契約提供消息的标準,交換的消息的規則。在WCF中,契約分4類:

·服務契約

·資料契約

·異常契約

·消息契約

(1)服務契約

服務契約分2種,

一種是用在接口或類上的服務契約,

[ServiceContract(Namespace="www.self001.com")]

public interface IFirstService

例如:CallbackContract用于在支援雙工交換的綁定裡設定回調類型

SessionMode,用于設定或取得會話的狀态

Name用于設定或取得wsdl上的<portType>元素的名稱

另一種是用在方法上的操作契約:

[OperationContract(Action="selfAction")]

void DoWork(string strContent);

例如:設定

IsOneWay,用于設定或取得是否進行單向消息交換

Name,用于設定或取得操作的名稱

通過對它們的屬性修飾達到對服務的限制和設定。

在BasicHttpBinding中,預設的消息交換模式為RR。現在為DoWork添加單向交換标志:

[OperationContract(IsOneWay=true)]

那麼在請求服務時,隻有去的消息,而不傳回消息。

(2)資料契約

主要用于資料的序列化。對于基元類型,wcf自動序列化并預設擁有資料契約。對複雜類型要進行序列化。(在WCF對複雜類型不用顯示添加資料契約,但如果添加了,那麼所有的資料契約都要添加)

資料的序列化為了傳輸和存儲,可見:

http://www.cnblogs.com/jams742003/archive/2010/03/31/1701184.html

[DataContract]

public class Customer

    [DataMember]

    public int Unid { get; set; }

    public string UserName { get; set; }

    public DateTime CreateTime { get; set; }

同樣的,資料契約也用于不同的地方:

通過屬性的設定來設定資料契約的細節,例如Namespace

在沒設定之前:

<s:Body>

  <GetCustomerResponse xmlns="www.self001.com">

    <GetCustomerResult

      xmlns:a="http://schemas.datacontract.org/2004/07/"

      xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

      <a:CreateTime>2010-04-01T00:00:00</a:CreateTime>

      <a:Unid>2</a:Unid>

      <a:UserName>Songjiang</a:UserName>

    </GetCustomerResult>

  </GetCustomerResponse>

</s:Body>

設定:

[DataContract(Namespace="selfdata.com")]

之後的情況是:

      xmlns:a="selfdata.com"

可以看到其中的變化。

[DataMember]

public int Unid { get; set; }

通過添加DataMember标簽,指定這個成員作為資料契約的一部分,且可以被序列化。它的屬性例如:

Order:擷取或設定成員的序列化和反序列化順序

Name:擷取或設定資料成員的名稱

[DataMember(Name="SelfId")]

      xmlns:a="selfdata.com"

      <a:SelfId>2</a:SelfId>

(3)異常契約

異常契約用于soap消息的異常。

[OperationContract]

[FaultContract(typeof(string))]

void SelfException();

public void SelfException()

throw new FaultException<string>

("error 007!","reason:Testing!");

用戶端:

public void TestFault()

FirstInstance.FirstServiceClient client =

new FirstInstance.FirstServiceClient();

    try

    {

client.SelfException();

    }

    catch (FaultException<string> ex)

Console.WriteLine(ex.Reason+" "+

ex.Detail.ToString());

列印資訊:reason:Testing! error 007!

包資訊:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">

  <s:Body>

    <s:Fault>

      <faultcode>s:Client</faultcode>

      <faultstring xml:lang="zh-CN">

        reason:Testing!

      </faultstring>

      <detail>

        <string

          xmlns="http://schemas.microsoft.com/2003/10/Serialization/">

          error 007!

        </string>

      </detail>

    </s:Fault>

  </s:Body>

</s:Envelope>

(4)消息契約

通過消息契約可以設定消息包體的多個選項,用于對包體中的類型進行強制設定。

[MessageContract(WrapperName="SelfCustomer")]

    [MessageBodyMember]

用戶端的用法就不同了:

public void TestCustomer()

FirstInstance.Customer customer =

new FirstInstance.Customer();

    int iUnid;

    string strUserName;

    client.GetCustomer(out iUnid,out strUserName);

看包:

  <SelfCustomer xmlns="www.self001.com">

    <CreateTime>2010-04-01T00:00:00</CreateTime>

    <Unid>2</Unid>

    <UserName>Songjiang</UserName>

  </SelfCustomer>

部落格園大道至簡

http://www.cnblogs.com/jams742003/

轉載請注明:部落格園

繼續閱讀