2009年5月12日 星期二

Windows Communication Foundation 新一代應用程式通訊架構

Windows Communication Foundation 新一代應用程式通訊架構

第1章 Windows Communication Foundation簡介


P.10
VS2005提供2種樣版來建立WCF Service
1. WCF Service Library Template
2. WCF Service Template



P.12
建立WCF Service Library Template時,要加入下列DAAB(Data Access Application Block)組件,你可以在C:\Program Files\Microsoft EnterpriseLibrary\bin資料夾中找到這些組件:
Microsoft.Practics.EnterpriseLibrary.Data.dll
Microsoft.Practics.EnterpriseLibrary.Common.dll
Microsoft.Practics.ObjectBuilder.dll
要加入引用:
using Microsoft.Practics.EnterpriseLibrary.Data;
using System.Data;

P.14
WCF是合約為主(Contract-First)的開發方式

P.15
[DataContract]這個屬性是用來辦識成型別的類別,以WCF技術中的XML串流序列化和還原序列化來傳輸。
使用WCF操作,型別的傳輸都必須能被WCF序列化。
每個型別都必須要加上[DataMember]屬性,如果沒有加上這個標籤的型別將不會被序列化。

P.16
使用ServiceContract屬性(Attribute)來讓介面成為服務合約,WCF runtime靠著有加入屬性的介面來產生中繼資料(metadata)供用戶端應用程式來使用服務。每一個能被外界呼叫的方法必須加上[OperationContract]屬性。

P.21
Web Service和網路應用程式所使用到的組件和程式碼會放在bin資料夾下,因此,在IIS設定WCF Service就像設定Web Service一樣,必須確定專案組件會放在[bin]資料夾下,而不是放在[bin\Debug]或是[bin\Release]資料夾下。

在選擇加入文字檔樣版(Text File Template),並把原檔名改成XXXX.svc後加入,這是Web Service的服務定義檔。

P.22
服務定義檔必須和Web Service有相同名稱,並以.svc副檔名結尾

P.23
Web.config中的<serviceModel>區塊包含有關WCF Web Service的設定,而<Service>區塊則有關每個服務的內容設定,<service>區塊內包含這個服務的命名空間和類別的一些設定。
<endpoint>區塊提供用戶端應用程式和服務溝通的服務明細。一個端點由三種資訊組成:網址(Address)、繫結(Binding)及合約(Contract)。其中網址指的是服務所在的應用程式網址,並且以.svc當成端點。
Binding則是有關存取Web Service的傳輸機制及所使用的通訊協定。

P.30
在WCF用戶端應用程式中,當需要與其它WCF Service溝通時,都會加入System.ServiceModel這個命名空間。

第2章 裝載WCF Service


P.35
在功能上,WCF Service只是一個物件,它提供一組可供用戶端應用程式呼叫的操作(operation)。當建立服務時,使用服務合約(Service Contract)來描述服務的操作,然後建立實作此合約的類別。

P.36
Binding包含下列的資訊:
傳輸協定
訊息的編碼格式
服務的安全性需求
服務的交易需求
服務通訊的可靠性

P.37
處理用戶端需求
channel負責處置一個訊息處理的方法,它是在服務Binding中被指定的

P.38
在channel stack中的channel是有順序性的。transport channel總是位於堆疊的最底層,而第一個channel則是負責從網路接收資料。在transport channel之上會是一個encoding channel。在channel stack內,這兩個channel是一定要出現的,而其它channel則是可選擇性的。

P.39
InstanceContextMode可使用的數值:
InstanceContextMode.PerCall
InstanceContextMode.PerSession
InstanceContextMode.Single

設定指定服務的InstanceContextMode屬性值:
[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession) ]

用戶端和服務需要使用包含一組相同Binding的Channel Stack

P.40
除了使用IIS Web Service來裝載WCF Service外,至少還有三種選擇。你可以使用建立一個一般的應用程式讓使用者啟動和停止WCF Service,或是可以在Windows Service內裝載WCF Service來讓系統在運行時能夠提供WCF Service。第三種選擇則是如果使用IIS 7.0,可以使用Windows Activation Service(WAS)。可以使用WAS來設定和裝載WCF Service而不使用到網路的發佈服務。但是,IIS7.0在XP上不能運行

P.50
產生proxy物件來連結服務,這能讓自已控制啟動服務的時間。
當存取Intranet中的服務時,使用TCP通訊協定將會更有效率

P.54
一個Binding包含一個或多個Binding項目。
一個Binding項目對應到一個channel。
Binding項目組成Binding的組合性提供非常大的彈性,但並不是所有的Binding項目組合都是合理的。

P.55
MTOM(Message Transmission Optimization Mechanism)
WCF函數庫中提供的Binding:
BasicHttpbinding
WSHttpbinding
WSDualHttpbinding
WSFederationbinding
NetTcpbinding
NetPeerTcpbinding
NetNamedPipebinding
NetMsmqbinding
MsmqIntegrationbinding

第3章 讓應用程式及服務更完整


P.83
回報非預期的Exception
如果使用強型別exception,則必須在服務合約中指定operation所有可能丟出的exception。如果服務丟出未定義的exception,exception的內容將不會傳送給用戶端(因為這個exception沒有WSDL描述來產生用戶端的proxy物件)。
如果要將exception送到用戶端,應該要觸發一般(非泛型)的FaultException

P.85
WCF runtime由DefaultExceptionHandler所抓取來產生沒有描述內容的SOAP錯誤:這個沒有內容的訊息實際上是一個安全性考量。
設定includeExceptionDetailInFaults屬性為True將使得WCF在產生非預期性的SOAP錯誤時,傳輸完整的exception內容

P.86
可以使用設定檔來指定服務的serviceDebug行為(behavior)。你可以使用ServiceBehavior屬性來報成相同目的。

P.87
建議還是在設定檔中啟用上述的behavior
一、可以在設定檔中啟用或停用此behavior,而不需重新建置應用程式
二、如果在程式碼啟用這個behavior,就不能在設定檔中停用它。如果在程式碼停用這個behavior,也不能在設定檔中啟動它
(Bear:換句話說,程式碼只要設定了這個behavior,那其它地方的設定就會被無條件覆蓋過去)

P.88
圖3-1,ServiceHost物件狀態轉換圖

第4章 保護企業級WCF Service


第5章 保護網際網路上的WCF Service


第6章 維護服務合約以及資料合約

(P.175~P.212)

P.189
C#允許在介面以及類別中擁有相同名稱的方法,只要用法不一樣就好,這就叫做多載(overloading)。因此,理論上可以建立任何方法的二種版本,一種沒有使用參數,一個則使用一個字串參數。但在SOAP標準卻不允許服務使用相同名稱的operation,所以這樣做會產生錯誤。
除了在C#介面中給予新不同名稱外,另一種替代的方法就是去設定service contract的OperationContract屬性的Name屬性,如下:
[OperationContract(Name="ListSelectedProducts"),....]
List ListProducts(string match)

WCF使用這個屬性去產生SOAP需求以及回應訊息的名稱。如果沒有設定Name屬性,WCF會使用方法的名稱代替,也要注意到,在service contract中operation的名稱會對SOAP需求以及回應訊息產生影響,因此變更operation的名稱對service contract來說,是個破壞性的變更。

P.190
新增operation到service contract中是個非破壞性的變更。新的用戶端應用程式可以傳送訊息給新的operation。現存的用戶端應用程式仍然可以繼續運作,只是不認得新的operation。
當定義新的service contract時,使用包含日期的Namespace屬性去識別版本,但是讓每個版本的Name屬性都保持一樣。請注意,如果調整Namespace以及Name屬性會導致破壞性的變更,因為這些是在用戶端以及服務之間拿來做為識別SOAP訊息的項目

P.191
....在這些介面中使用超過一次的方法,只要在類別中實作一次就可以了

P.192
列表6-1:對於Service Contract實作破壞性與非破壞性變更

P.193 倒數第2組翻錯了,(新增)>>(移除)
原文: Removing a parameter from an operation

P.194 第2行好像有錯字,(產)>>(重)
原文: If client applications use WCF proxies, you will need to regenerate these proxies.

P.194
如果對service contract造成破壞性變更,需要去更新用戶端程式。如果用戶端程式使用WCF proxy物件,你就要去重新產生proxy物件。但是建議的作法是,調整service contract後去建立新版的service contract,然後讓舊版本繼續運作。這樣就不用再去更新原有用戶端應用程式,但是原有用戶端程式也不能使用服務的新功能。

WCF runtime使用.NET Framework內建的序列化功能來序列化(serialize)以及反序列化(deserialize).NET Framework原生的資料型別,像是integer, real, numbers或是string。對於更複雜的型別,服務必須額外指定序列化的格式,有多種方法可以描述像XML這樣的資料結構。可以使用data contract來定義結構型別。然後WCF runtime可以使用data contract序列化物件(DataContractSerializer類別的執行個體)序列化和反序列化這些型別。

P.197
data contract序列化物件以字母順序來序列化在data contract中的成員。為了不要讓程式自行處理排列順序,建議設定DataMember屬性的Order屬性來明確指定成員順序。

data contract序列化物件將會依照Order屬性值的大小(由小到大)來序列化成員。如果成員擁有相同的Order屬性值,則相同值的成員會依照字母順序排列。

P.198
和service contract一樣,data contract序列化物件使用每個data contract名稱作為序列化欄位的名稱。因此修改data member名稱會造成破壞性變更。和service contract內的ooperaction一樣,對於data member必須提供邏輯名稱,這樣data contract序列化物件才能用來代替data member的實體名稱(透過設定DataMember屬性的Name屬性)。可以透過這功能讓邏輯名稱保持一樣,但是實體名稱可以修改。

P.203
新增這個Order屬性設定為0的成員會讓它在序列化時作為data contract的第二個成員。因為Name這個成員也有相同的屬性值,但是依照字母排列,Name成員會先輸出。

P.208
Data Contract相容性
如果你需要設定data contract的版本,應該要去維持和原有用戶端程式的相容性。DataMember屬性提供兩種可用的屬性:
IsRequired: 如果設定這個屬性為True,服務所收到的SOAP訊息必須要在data member中包含其值。這個屬性預設為False,所以會為每個遺漏的欄位產生預設值。
EmitDefaultValue: 設定這個屬性為True,如果欄位值沒有包含在用戶端傳送的SOAP訊息時,用戶端WCF runtime會為這個遺漏的欄位產生預設值。預設值為True。

如果要維持未來服務版本要嚴謹地遵從data contract,在建立第一版的服務時,就要為每個data member設定IsRequired屬性值為True,以及EmitDefaultValue屬性值為False。如果在前一版設定後(IsRequired屬性設定為False),後面的版本就不能再去變更(IsRequired屬性設為True)。

P.209
Round-tripping(往返)


第7章 維護服務狀態及序列作業


(P.213~P.250)

P.213
以購物車為例,描述購物車內的項目資料要放置的位置,至少有兩個選擇:
一、在用戶端程式維護購物車。
傳遞描述購物車購買內容作為參數給每個operation,處理後回傳更新後的結果給用戶端程式。
無法避免用戶端應用程式內的cookie資料直接被竄改,使用cookie也有安全上的風險,許多瀏覽器提供讓使用者可以停用cookie的功能。
在WebService的環境中(相對於Web應用程式以及瀏覽器的組合),用戶端程式可以使用程式碼而不是cookie來維護狀態資訊,但這種作法會把用戶端程式和Web Service綁在一起。
二、在服務中維護購物車資訊。
在WCF的環境下,用戶端程式和服務之間的互動都是透過呼叫ServiceContract中明確定義(Well-Defined)的operation,而且用戶端應用程式不需要知道服務如何實作購物車。

P.218
(檢查使用者是否新增..) >> (檢查使用者是否[已經]新增..)
原文: Check to see whether the user has already added this product to the shopping cart

P.225
也可以在[專案]功能表中選擇Add Service Reference來產生HTTP服務的proxy物件,然後將這個物件新增到用戶端專案中。但是服務必須要在VS2005上才可以這樣設定,而且服務也要啟動中繼資料(metadata)發佈(這個功能預設為停用)。

P.228
圖有錯

P.229
如果使用TCP或是name pipe來做傳輸,可以在Binding設定的MaxConnections屬性中設定值來限制最大並行數。這些傳輸方法預設為10個連接。
你可以使用服務的ServiceBehavior屬性的InstanceContextMode屬性來控制服務執行個體和用戶端程式間的關係。
InstanceContextMode屬性可以設定成下列三種值之一:InstanceMode.PerSession, InstanceMode.PerCall, and InstanceMode.Single

P.230
PerSession執行個體內容模示
服務執行個體對於session來說是私用的。每一次用戶端程式建立一個新的session,它就會取得一個新的服務執行個體。在使用這個執行個體內容模示時,即使兩個session都是由同一個用戶端程式所建立,這兩個session還是不能共用同一個服務執行個體。

P.231
PerCall執行個體內容模示
這個執行個體內容模式的缺點就是很難維護每個operation之間的狀態。
Single執行個體內容模示
使用同一個執行個體來處理後續的用戶端需求,而且每個用戶端會連結到同一個服務。

P.236
使用者帳號可能包含帶有分隔符號[\]的網域名稱。這個字元在檔案名稱中是不能使用的,所以要寫程式碼來代替這個分隔符號[\],而且另一個符號[!]也不能使用。

第8章 支援交易


第9章 實作可靠的訊息傳輸


第10章 寫程式來控制設定以及通訊


第11章 實作單向以及非同步化作業


第12章 實作良好效能的WCF Service


第13章 傳閱訊息


第14章 使用回呼合約來發佈和訂閱事件


第15章 使用Windows CardSpace管理身份識別


第16章 與ASP.NET用戶端及Enterprise Services元件之間的整合