如何从使用WCF客户端的响应中读取自定义SOAP头
问题描述:
所以我的问题是:当服务是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
返回null
而reply.Headers.FindHeader
发现里面AfterReceiveReply
2.扩展OperationResultContextExtension
正确的头看起来相当顺利,为什么我在OperationContext.Current.Extensions.Find<OperationResultContextExtension>()
得到null
。
3.是否有一些更好/更简单或至少有效的方式从响应中获取这个头文件?
答
我也有类似的问题这一点,在我的情况我解决它通过将客户呼叫OperationContestScope
ManagerSoapClient client = new ManagerSoapClient();
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
client.Authenticate(...); // <---- The change
var headers = OperationContext.Current.IncomingMessageHeaders;
}
我试过这个方法里面,但是在“标题”对象的所有字段都为空,即使在Fiddler中我可以看到诸如Action,To和From等标题字段。有任何想法吗? – AntonK 2015-08-02 23:10:10