2012-04-11 156 views
1

所以我的問題是:當服務是asmx時,我無法使用生成的wcf代理(服務引用)從Web服務響應中獲取頭。如何從使用WCF客戶端的響應中讀取自定義SOAP頭

ManagerSoapClient client = new ManagerSoapClient(); 
client.Authenticate(...); 
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
{ 
    //headers = null 
    var headers = OperationContext.Current.IncomingMessageHeaders; 
} 

這很奇怪,因爲SOAP響應有一些頭:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <soap:Header> 
     <OperationResult xmlns="http://tempuri.org/"> 
     <Status>Success</Status> 
     </OperationResult> 
    </soap:Header> 
    <soap:Body> 
     ... 
    </soap:Body> 
</soap:Envelope> 

好吧,我添加了自定義IClientMessageInspector檢查標題:

public class OperationResultMessageInspector : IClientMessageInspector 
{ 
    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    {   
     return channel; 
    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     //It founds header at position 0!! 
     int headerIndex = reply.Headers.FindHeader("OperationResult", "http://tempuri.org/"); 
    } 
} 

於是就有畢竟是一個頭..但爲什麼我不能使用OperationContext.Current.IncomingMessageHeaders訪問它?

好的。現在我只想將此標題保存在某個地方,以便在服務呼叫後能夠訪問它。我決定使用擴展IExtension<OperationContext>
所以我的代碼,現在是下一個:

public class ManagerProxy 
{ 
    public void Authenticate() 
    { 
     ManagerSoapClient client = new ManagerSoapClient(); 
     client.Endpoint.Behaviors.Add(new OperationResultBehavior()); 
     client.Authenticate(...); 

     using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
     { 
      //headers = null 
      var headers = OperationContext.Current.IncomingMessageHeaders; 
      //header = null 
      OperationResultContextExtension header = OperationContext.Current.Extensions.Find<OperationResultContextExtension>(); 
     } 
    } 
} 

public class OperationResultMessageInspector : IClientMessageInspector 
{ 
    public object BeforeSendRequest(ref Message request, IClientChannel channel) 
    {   
     return channel; 
    } 

    public void AfterReceiveReply(ref Message reply, object correlationState) 
    { 
     IClientChannel channel = (IClientChannel)correlationState; 

     //It founds header at position 0!! 
     int headerIndex = reply.Headers.FindHeader("OperationResult", "http://tempuri.org/"); 
     XmlDictionaryReader reader = reply.Headers.GetReaderAtHeader(headerIndex); 

     OperationResultContextExtension extension = new OperationResultContextExtension 
     { 
      SomeData = reader.ReadString() 
     };   

     using (OperationContextScope scope = new OperationContextScope(channel)) 
     {    
      OperationContext.Current.Extensions.Add(extension); 
     } 
     reader.Close(); 
    } 

} 

public class OperationResultContextExtension : IExtension<OperationContext> 
{ 
    public string SomeData { get; set; } 
    public void Attach(OperationContext owner) { } 
    public void Detach(OperationContext owner) { } 
} 

public class OperationResultBehavior : IEndpointBehavior 
{ 
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } 
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { } 
    public void Validate(ServiceEndpoint endpoint) { } 
    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
    { clientRuntime.MessageInspectors.Add(new OperationResultMessageInspector()); } 
} 

它應該工作,卻不料我OperationContext.Current.Extensions.Find<OperationResultContextExtension>();null爲好。

因此,有我的問題:
1.爲什麼OperationContext.Current.IncomingMessageHeaders返回nullreply.Headers.FindHeader發現裏面AfterReceiveReply
2.擴展OperationResultContextExtension正確的頭看起來相當順利,爲什麼我在OperationContext.Current.Extensions.Find<OperationResultContextExtension>()得到null
3.是否有一些更好/更簡單或至少有效的方式從響應中獲取這個頭文件?

回答

3

我也有類似的問題這一點,在我的情況我解決它通過將客戶呼叫OperationContestScope

ManagerSoapClient client = new ManagerSoapClient(); 

using (OperationContextScope scope = new OperationContextScope(client.InnerChannel)) 
{ 
    client.Authenticate(...); // <---- The change 
    var headers = OperationContext.Current.IncomingMessageHeaders; 
} 
+0

我試過這個方法裏面,但是在「標題」對象的所有字段都爲空,即使在Fiddler中我可以看到諸如Action,To和From等標題字段。有任何想法嗎? – AntonK 2015-08-02 23:10:10

相關問題