だから私の問題があります: サービスが 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. 応答からこのヘッダーを取得するための、より優れた/より単純な、または少なくともうまく機能する方法はありますか? null
reply.Headers.FindHeader
AfterReceiveReply
OperationResultContextExtension
null
OperationContext.Current.Extensions.Find<OperationResultContextExtension>()