Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing C# client to consume a Java web service that returns array of objects

I am writing a C# client that calls a web service written in Java (by another person). I have added a web reference to my client and I'm able to call methods in the web service ok.

The service was changed to return an array of objects, and the client does not properly parse the returned SOAP message.

MyResponse[] MyFunc(string p)

class MyResponse
{
    long id;
    string reason;
}

When my generated C# proxy calls the web service (using SoapHttpClientProtocol.Invoke), I am expecting a MyResponse[] array with length of 1, ie a single element. What I am getting after the Invoke call is an element with id=0 and reason=null, regardless of what the service actually returns. Using a packet sniffer, I can see that the service is returning what appears to be a legitimate soap message with id and reason set to non-null values.

Is there some trick to getting a C# client to call a Java web service that returns someobject[] ? I will work on getting a sanitized demo if necessary.

Edit: This is a web reference via "Add Web Reference...". VS 2005, .NET 3.0.

like image 485
David Chappelle Avatar asked Sep 15 '08 17:09

David Chappelle


1 Answers

Thanks to Xian, I have a solution.

The wsdl for the service included a line

<import namespace="http://mynamespace.company.com"/>

The soap that the client sent to the server had the following attribute on all data elements:

xmlns="http://mynamespace.company.com"

But the xml payload of the response (from the service back to the client) did not have this namespace included. By tinkering with the HTTP response (which I obtained with WireShark), I observed that the .NET proxy class correctly picked up the MyResponse values if I forced the xmlns attribute on every returned data element.

Short of changing the service, which I don't control, the workaround is to edit the VS generated proxy class (eg Reference.cs) and look for lines like this:

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://mynamespace.company.com")]
public partial class MyResponse {

and comment out the XmlType attribute line. This will tell the CLR to look for response elements in the default namespace rather than the one specied in the wsdl. You have to redo this whenever you update the reference, but at least it works.

like image 158
David Chappelle Avatar answered Nov 15 '22 18:11

David Chappelle