【问题标题】:How to read custom SOAP header from response using WCF client如何使用 WCF 客户端从响应中读取自定义 SOAP 标头
【发布时间】:2012-04-11 16:34:22
【问题描述】:

所以我的问题是:当服务是 asmx 时,我无法使用生成的 wcf 代理(服务引用)从 Web 服务响应中获取标头。

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&lt;OperationContext&gt;
所以我的代码现在是下一个:

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&lt;OperationResultContextExtension&gt;(); 也是null

所以有我的问题:
1. 为什么OperationContext.Current.IncomingMessageHeaders 返回nullreply.Headers.FindHeaderAfterReceiveReply 中找到正确的标题
2.扩展OperationResultContextExtension看起来很流畅,为什么我在OperationContext.Current.Extensions.Find&lt;OperationResultContextExtension&gt;()期间得到null
3.是否有更好/更简单或至少工作良好的方法来从响应中获取此标头?

【问题讨论】:

    标签: .net wcf service header


    【解决方案1】:

    我遇到了类似的问题,在我的情况下,我通过将客户端调用放在 OperationContestScope 中来解决它

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

    【讨论】:

    • 我尝试了这种方法,但是“headers”对象中的所有字段都是空的,即使在 Fiddler 中我可以看到诸如 Action、To 和 From 等标题字段。有什么想法吗?
    • @AntonK 发现任何工作? :) OCT2018 - WCF @ .NET4.5
    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    • 2017-02-22
    • 2023-02-14
    • 2018-12-04
    相关资源
    最近更新 更多