This type of problem generally appears in interop scenarios where client could be .net application and service could be java web service.
- .net client application is able to send request.
- Java service is able to read the request.
- Java service is able to send the response.
- However, .net client application is not able to read the response. Client application is just able to read the content as null. Interestingly in fiddler (a web traffic tool) or in netmon (a network monitor tool), we can see actual SOAP payload in response. Question appears why .net is not able to read the payload.
It primarily happens due to namespace conflict in xsd-complex-type-elements. In other words, message could not be properly de-serialized to the structure of .net classes. As a best practice, wsdl can be modified. In some cases, .net applications do not have control over web service side (as in vendor).
From WCF traces as well as SOAP UI tool, we identified the response appears as:
- Open response editor for the method in SOAP UI
- Paste the same content (from WCF traces or use SOAP UI response)
- Right click on the editor
- Select Validate
- Validation is unsuccessful
- In my case, validation pointed that it has issues with AccountResult node.
- Applied ns2:AccountResult in place of AccountResult. Validation was successful.
It is safe to claim on payload modification, response can properly be de-serialized in the .net side.
We need to apply code changes in the .net side.
- Create a new class CustomInspector (implement IClientMessageInspector) and modify AfterReceiveReply method to correct the anomaly.
public class CustomInspector: IClientMessageInspector
public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
// Read reply payload
XmlDocument doc = new XmlDocument();
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms);
ms.Position = 0;
// Change logic
// Write the reply payload
writer = XmlWriter.Create(ms);
ms.Position = 0;
XmlReader reader = XmlReader.Create(ms);
reply = System.ServiceModel.Channels.Message.CreateMessage(reader, int.MaxValue, reply.Version);
void ChangeMessage(XmlDocument doc)
string xml = doc.OuterXml;
// Apply the xml modification logic here
// Replace can be applied as a pure string replacement for string types
xml = xml.Replace("AccountResult", "ns2:AccountResult");
public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, System.ServiceModel.IClientChannel channel)
2. Create a custom class CustomValidationBehavior (implement IEndpointBehavior) and modify logic for ApplyClientBehavior method.
public class CustomValidationBehavior: IEndpointBehavior
public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
public void ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
public void ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher)
public void Validate(ServiceEndpoint endpoint)
3. Now, we need to associate this custom endpoint behavior with the service proxy instance as in:
AccountServiceReference.Service1Client proxy = new AccountServiceReference.Service1Client();
// Make service method calls
// Get results
4. Client should be able to read the response payload successfully for all nodes. If it has any issues with a particular xml node, we need to identify if any element does not fit in with wsdl defined SOAP namespace.
5. If the similar situation applies in case of a WCF service where client is java, service can take advantage of custom IDispatchMessageInspector in reverse to IClientMessageinspector.
Note: There are certain code formatting challenges in the shared codes above. Please consider the connected blocks of code as a single unit. Keep coding!
Hope this helps!
Purna Chandra Panda (MSFT)