1

だから私の問題があります: サービスが 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ですか?

Ok。ここで、このヘッダーをどこかに保存して、サービス呼び出し後にアクセスできるようにしたいだけです。拡張機能を使用することにした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に戻るのはなぜ 2. 拡張機能は非常にスムーズに見えるのですか? 3. 応答からこのヘッダーを取得するための、より優れた/より単純な、または少なくともうまく機能する方法はありますか? nullreply.Headers.FindHeaderAfterReceiveReply
OperationResultContextExtensionnullOperationContext.Current.Extensions.Find<OperationResultContextExtension>()

4

1 に答える 1