Jump to content

Problem with C# webservice client

- - - - -

  • Please log in to reply
8 replies to this topic

#1
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
Hello Everybody!

I hope someone can help me with a problem I have with C# and a SOAP webservice.

I am using visual studio 2010, and I added a soap webservice as a web reference.

Now I'm trying to call a function of that webservice that returns a 2 dimensional array. But I get an exception at the C# side that states there is an error in the XML document.

When I call the same soap function from a PHP client it parses the response correctly.

The webservice server is made in PHP, and the WSDL file is generated dynamically.

I have to say I'm new to SOAP so it could be an error in either the WSDL file or the respone.

WSDL:
<?xml version="1.0" ?> 

<definitions name="Test" targetNamespace="urn:Test" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 	xmlns:tns="urn:Test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 	xmlns="http://schemas.xmlsoap.org/wsdl/">

	<types xmlns="http://schemas.xmlsoap.org/wsdl/">

		<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Test">

			<complexType name="ArrayOfStrings">

				<complexContent>

					<restriction base="SOAP-ENC:Array">

						<attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]" /> 

					</restriction>

  				</complexContent>

	  		</complexType>

			<complexType name="EmployeePersonalData">

				<complexContent>

					<restriction base="SOAP-ENC:Array">

						<attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="tns:ArrayOfStrings[]" /> 

					</restriction>

				</complexContent>

			</complexType>

		</schema>

	</types>

	<message name="getAllEmployeesRequest">

		<part name="requestedFields" type="tns:ArrayOfStrings" /> 

	</message>

	<message name="getAllEmployeesResponse">

		<part name="result" type="tns:EmployeePersonalData" /> 

	</message>

	<portType name="TestPort">

		<operation name="getAllEmployees">

			<input message="tns:getAllEmployeesRequest" /> 

			<output message="tns:getAllEmployeesResponse" /> 

		</operation>

	</portType>

	<binding name="TestBinding" type="tns:TestPort">

		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> 

		<operation name="getAllEmployees">

			<soap:operation soapAction="http://schemas.xmlsoap.org/soap/envelope/#EmployeeData#getAllEmployees" /> 

			<input>

				<soap:body use="encoded" namespace="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> 

			</input>

			<output>

				<soap:body use="encoded" namespace="http://schemas.xmlsoap.org/soap/envelope/" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> 

			</output>

		</operation>

	</binding>

	<service name="TestService">

		<documentation /> 

		<port name="TestPort" binding="tns:TestBinding">

			<soap:address location="http://localhost/services/service.php" /> 

		</port>

	</service>

</definitions>

Response:
<?xml version="1.0" encoding="UTF-8" ?> 

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Test" 	xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">

	<SOAP-ENV:Body>

		<SOAP-ENV:getAllEmployeesResponse>

			<result SOAP-ENC:arrayType="ns1:ArrayOfStrings[2]" xsi:type="ns1:EmployeePersonalData">

				<item SOAP-ENC:arrayType="xsd:string[2]" xsi:type="ns1:ArrayOfStrings">

					<item xsi:type="xsd:string">1</item> 

					<item xsi:type="xsd:string">2</item> 

				</item>

				<item SOAP-ENC:arrayType="xsd:string[2]" xsi:type="ns1:ArrayOfStrings">

					<item xsi:type="xsd:string">3</item> 

					<item xsi:type="xsd:string">4</item> 

				</item>

			</result>

		</SOAP-ENV:getAllEmployeesResponse>

	</SOAP-ENV:Body>

</SOAP-ENV:Envelope>


#2
wwarren

wwarren

    Learning Programmer

  • Members
  • PipPipPip
  • 60 posts
I've seen this before....it's really weird

When you compile your project, .NET actually generates code and classes based off the WSDL. Then your code call call these classes and methods etc.
Problem is...when visual studio converts the WSDL into C# classes, it does it wrong.

I was working with a webservice that had a method which returned an array. I kept getting errors complaining that it was supposed to be returning 2 dimensional arrays. I was like...um...no.

So i did some digging online, and found out about this weird bug-type thing. Visual Studio uses a program called wsdl.exe to do the converting and apparently it does it wrong sometimes.
So how do you make it work properly? In short....hack it.

You have to manually use wsdl.exe to generate a giant C# class, and then compile that right into your project. When I ran it, it would define the methods like this:

public int[][] methodThatReturnsAnArray()

when it should have only been a one-dimensional array. I had to generate the class using wsdl.exe and then find and replace "[][]" with "[]" and it works great.

Let me know if you have any luck with this lol

#3
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
I'll have to try that tomorrow (I don't have any time today unfortunately).

But I do know the function that was generated by vs2010 does return a 2d array (as I expected). But it gives me an error when it tries to parse the XML response.

#4
wwarren

wwarren

    Learning Programmer

  • Members
  • PipPipPip
  • 60 posts
Yeah, but wsdl.exe might be generating them as 3d or 4d arrays. Give it a shot and let me know if you have any success

#5
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
So i've tried it, but it generates thesame result as the automaticaly generated code.:crying:

#6
wwarren

wwarren

    Learning Programmer

  • Members
  • PipPipPip
  • 60 posts
Oh no, don't cry...

Open up the .cs file that wsdl.exe generated and do a search for the name of your array method and see if it is defined as it should be.

#7
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
Hahah no worries.

Its defined like this:
    [System.Web.Services.Protocols.SoapRpcMethodAttribute("http://schemas.xmlsoap.org/soap/envelope/#EmployeeData#getAllEmployees", RequestNamespace="http://schemas.xmlsoap.org/soap/envelope/", ResponseNamespace="http://schemas.xmlsoap.org/soap/envelope/")]

    [return: System.Xml.Serialization.SoapElementAttribute("result")]

    public string[][] getAllEmployees(string[] requestedFields) {

        object[] results = this.Invoke("getAllEmployees", new object[] {

                    requestedFields});

        return ((string[][])(results[0]));

    }

Which looks okay to me..

#8
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
Anybody any idea what could be the problem?

#9
rico

rico

    Newbie

  • Members
  • Pip
  • 6 posts
Anyone?




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users