在调用 Web 服务时,是否有一种简单的方法来获取请求的 soap 消息和响应的 soap 消息?

Is there an easy way to get the soap message for the request and the soap message for the response, when invoking the web service?

我想调用一个网络服务,我想获取请求和响应对象作为肥皂消息。

var response = client.invoke(parameter);

我想以某种方式发送消息并接收消息。

根据 Carlos Figueira 的 MSDN 文章 WCF Extensibility – Message Inspectors,一种选择是使用 MessageInspector。

创建一个实现 EndBehavior and ClientMessageInspector 的 class。缓冲请求和回复消息,以便稍后使用它们。在这个例子中,我在控制台中打印它们。

这里是组合实现:

// using System.ServiceModel.Description;
// using System.ServiceModel.Dispatcher;
// using System.ServiceModel.Channels;
// using System.ServiceModel
public class InspectBehaviorAndnspector : IEndpointBehavior, IClientMessageInspector
{

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.MessageInspectors.Add(this);
    }

    public MessageBuffer RequestBuffer;
    public MessageBuffer ReplyBuffer;

    public void AfterReceiveReply(ref Message reply, object correlationState){
       // messages are read only
       ReplyBuffer = reply.CreateBufferedCopy(2048);
       // so recreate the message after it was buffered
       reply = ReplyBuffer.CreateMessage();
    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel){
       // messages are read only
       RequestBuffer = request.CreateBufferedCopy(2048);
       // so recreate the message after it was buffered
       request = RequestBuffer.CreateMessage();
       return "42";
    }

    // not needed for client
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
    }

    public void Validate(ServiceEndpoint sep) 
    {
    }
    public void AddBindingParameters(ServiceEndpoint sep, BindingParameterCollection bpc)
    {
    }
}

现在,在您的 client 实例上,假设它派生自 ClientBase,您可以:

var inspector = new InspectBehaviorAndnspector();
client.Endpoint.Behaviors.Add(inspector);

// this is your call
var response = client.invoke(parameter);

// either do a ToString
Console.WriteLine(inspector.RequestBuffer.CreateMessage().ToString());
// or Write it with XmlWriter
var sb = new StringBuilder();
using(var xw = XmlWriter.Create(sb, new XmlWriterSettings {Indent =true})) {
    inspector.ReplyBuffer.CreateMessage().WriteMessage(xw);
}
Console.WriteLine(sb.ToString());

我在一个带有添加服务的示例中有 运行 这个,这是我的结果:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/ISelfHostTest/Add</Action>
  </s:Header>
  <s:Body>
    <Add xmlns="http://tempuri.org/">
      <x>3</x>
      <y>2</y>
    </Add>
  </s:Body>
</s:Envelope>

<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Body>
    <AddResponse xmlns="http://tempuri.org/">
      <AddResult>5</AddResult>
    </AddResponse>
  </s:Body>
</s:Envelope>