2012-05-23 66 views
2

我想實現一個使用WCF通過HTTP接受SOAP 1.2的Web服務。不幸的是,我必須與不發送action參數的傳統客戶端一起使用,作爲HTTP標頭的一部分。這似乎是導致WCF的問題,WCF(至少默認)似乎無法將請求路由到適當的地方,而不是action使用WCF實現不需要動作頭的SOAP服務器

我創建了一個基於BasicHttpBinding但隨着MessageVersion設置爲MessageVersion.Soap12,我認爲將消除使用WS-Addressing的要求具有約束力。

然後我在IContractBehavior超載ApplyDispatchBehaviour設置DispatchRuntime.OperationSelectorIDispatchOperationSelector定製的實現,選擇基於SOAP體內容的正確操作(基本上是this MSDN article使用的方法)

默認情況下,這似乎並不工作,並且在發出請求時不會調用SelectOperation函數。

但是,如果我在一個虛擬操作上添加一個空的動作,以我的合同,就像這樣:

[OperationContract(Action = "")] 
void DoNothing(); 

然後突然SelectOperation開始叫我的代碼按預期工作。看起來我一直在使WCF不再需要動作頭 - 我剛剛停止了用於直接映射到操作的動作頭。但是,由於合同是從.wsdl文件生成的,因此編輯它以使事情發揮作用似乎是一個非常糟糕的駭客。

所以我的問題是這樣的:我怎麼能接受沒有使用WCF的操作頭的SOAP 1.2請求?除非我誤解了SOAP 1.2規範並不需要動作頭,那麼肯定有一些方法可以在不借助合同的情況下通過WCF實現這一點?

+0

您可以使用Action =「*」,然後單個操作將捕獲所有請求 - 但我不認爲這是理想的嗎? – Chris

+0

@Chris不幸的是,再次,這將是黑客生成的文件,我寧願避免。除非有一些選擇,我可以傳遞給'svcutil.exe'生成wsdl文件的接口時,會實現這一目標嗎? – obmarg

回答

1

我剛纔設法找出了今天這個問題的答案。事實證明,使用的EndpointDispatcherActionMessageFilter,因爲它是ContractFilter,這是根據操作過濾掉消息。

我更新了ContractFilterMatchAllMessageFilter後,然後所有的消息都穿過我的IDispatchOperationSelector在那裏他們可以基於SOAP主體的內容進行選擇。

我以前做的代碼,這是在IContractBehavior.ApplyDispatchBehaviour

foreach(
    var endpointDispatcher in 
    dispatchRuntime.ChannelDispatcher.Endpoints 
    ) 
{ 
    endpointDispatcher.ContractFilter = new MatchAllMessageFilter(); 
} 

我可能會在將來更新用更適當的過濾器比MatchAllMessageFilter,但現在它正在做的工作。

相關問題