In this post I will explain how to trace the raw xml for each request and response sent between client/server for Soap/WCF Services.
I found this idea/code from stackoverflow post:
how to trace soap xml as a webservice client in netcore?
.
You need to create two classes
-
One is
InspectorBehaviorto implmentIEndpointBehaviorinterface. -
Second is
MyMessageInspectorwhich implements theIClientMessageInspectorinterface.
The InspectorBehavior class will use the ApplyClientBehavior() method to add the real message inspector by calling Add() method on ClientMessageInspectors collection for clientRuntime object.
clientRuntime.ClientMessageInspectors.Add(myMessageInspector);
Further in MyMessageInspector class, we can retreive and save the Request and Response Xml content in local variables/properties in these two methods.
- BeforeSendRequest
- AfterReceiveReply
Complete code listing for MyMessageInspector class is:
public class MyMessageInspector : IClientMessageInspector
{
public string LastRequestXML { get; private set; }
public string LastResponseXML { get; private set; }
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply,
object correlationState)
{
LastResponseXML = reply.ToString();
}
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request,
System.ServiceModel.IClientChannel channel)
{
LastRequestXML = request.ToString();
return request;
}
}
Code listing for InspectorBehavior class is:
public class InspectorBehavior : IEndpointBehavior
{
public string LastRequestXML
{
get
{
return myMessageInspector.LastRequestXML;
}
}
public string LastResponseXML
{
get
{
return myMessageInspector.LastResponseXML;
}
}
private MyMessageInspector myMessageInspector = new MyMessageInspector();
public void AddBindingParameters(ServiceEndpoint endpoint,
System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceEndpoint endpoint,
EndpointDispatcher endpointDispatcher)
{
}
public void Validate(ServiceEndpoint endpoint)
{
}
public void ApplyClientBehavior(ServiceEndpoint endpoint,
ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(myMessageInspector);
}
}
I used the WFC service instance created by Visual Studio template with default two methods GetData() and GetDataUsingDataContract();
When calling the service methods on the client side, you can simply add the custom EndpointBehavior (InspectorBehavior)
on the service client instance object.
ServiceReference1.Service1Client service1Client = new ServiceReference1.Service1Client(); var requestInterceptor = new InspectorBehavior(); service1Client.Endpoint.EndpointBehaviors.Add(requestInterceptor);
After service method call, you can get the Request and Response Xml content by requestInterceptor's properties:
string str1 = service1Client.GetDataAsync(1).GetAwaiter().GetResult(); string req1Xml = requestInterceptor.LastRequestXML; string res1Xml = requestInterceptor.LastResponseXML;
Here is the sample of raw sample I received by above call.
Request
<?xml version="1.0" encoding="utf-16"?>
<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/IService1/GetData</Action>
</s:Header>
<s:Body>
<GetData xmlns="http://tempuri.org/">
<value>1</value>
</GetData>
</s:Body>
</s:Envelope>
Response
<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<GetDataResponse xmlns="http://tempuri.org/">
<GetDataResult>You entered: 1</GetDataResult>
</GetDataResponse>
</s:Body>
</s:Envelope>
Call the second method, and get the Request and Response Xml content by same properties:
ServiceReference1.CompositeType compositeType = new ServiceReference1.CompositeType();
compositeType.BoolValue = true;
compositeType.StringValue = "some text";
ServiceReference1.CompositeType compositeTypeRes =
service1Client.GetDataUsingDataContractAsync(compositeType).GetAwaiter().GetResult();
string req2Xml = requestInterceptor.LastRequestXML;
string res2Xml = requestInterceptor.LastResponseXML;
Here is the sample of raw sample I received by above call.
Request
<?xml version="1.0" encoding="utf-16"?>
<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/IService1/GetDataUsingDataContract</Action>
</s:Header>
<s:Body>
<GetDataUsingDataContract xmlns="http://tempuri.org/">
<composite xmlns:d4p1="http://schemas.datacontract.org/2004/07/WcfService1"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<d4p1:BoolValue>true</d4p1:BoolValue>
<d4p1:StringValue>some text</d4p1:StringValue>
</composite>
</GetDataUsingDataContract>
</s:Body>
</s:Envelope>
Response
<?xml version="1.0" encoding="utf-16"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header />
<s:Body>
<GetDataUsingDataContractResponse xmlns="http://tempuri.org/">
<GetDataUsingDataContractResult xmlns:a="http://schemas.datacontract.org/2004/07/WcfService1"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:BoolValue>true</a:BoolValue>
<a:StringValue>some textSuffix</a:StringValue>
</GetDataUsingDataContractResult>
</GetDataUsingDataContractResponse>
</s:Body>
</s:Envelope>
References:
Thanks for your blog.
ReplyDeleteBest Website Development Company in Coimbatore
Best Integrated E-Commerce Solutions in Coimbatore, India | Repute