Skip navigation.
 
mlRe: Complex data for webservices
FROM : Niklas Saers
DATE : Thu Apr 24 10:31:24 2008

Hi Jeff,
thanks again for answering so quickly

On Apr 23, 2008, at 4:25 PM, Jeff LaMarche wrote:

> When I try to access your WSDL, I get:
> Server Error in '/DummyWS' Application.


Sorry about that, should be fixed now. Seems the development box ran 
out of diskspace. :-/

> Generally, though, I don't believe the response from a web service 
> is a dictionary - I believe it's usually a string and I'm wondering 
> why you are sending an empty dictionary - it would seem like nil 
> would be a better choice if you want to send without any data.


Perhaps I misunderstood, but I thought an empty dictionary means no 
arguments? Passing nil is not an option as it gives this error:
*** -[NSCFDictionary initWithObjects:forKeys:count:]: attempt to 
insert nil value at objects[0] (key: parameters)

Passing an empty string is still passing an argument, and I still get 
testStr==nil when I do:
   NSString *testStr = (NSString*) [myService testString:@""];

I also tried passing an empty NSArray thinking that it would be a nice 
way of representing parameters, but again I got testStr==nil

The reason I  expect that the regular parameter will be a dictionary 
is that I would like to pass objects back and forth. For instance, in http://78.157.102.46:2234/DummyWS/Service1.asmx
  I've defined getValidAuth() that returns a valid Authentication 
object, and I would like to do something like

NSDictionary *authDict = [WS getValidAuth];
NSNumber *successBool = [WS testAuth:authDict];
if(successBool.boolValue)
  NSLog(@"Success");
else
  NSLog(@"Fail");


One issue I've become more suspiscious

> Also, you are leaking memory there since your code will never 
> release the dictionary you allocated in the first line of your method.


I've turned on garbage collection, so I didn't worry about that.

> Let's see, what else...
> You say there is some network activity, so why don't you try using 
> tcpdump to see what is being passed back and forth. It would be 
> something like this in a terminal window:
> sudo tcpdump -s 0 -v -A -i en1 port 2234


Sure. This is a valid SOAP request for testString:

POST /DummyWS/Service1.asmx HTTP/1.1
User-Agent: Mac OS X; WebServicesCore.framework (1.0.0)
Host: 78.157.102.46:2234
Content-Type: text/xml
Soapaction: http://webservice.mydomain.com/testString
Content-Length: 530
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
  <SOAP-ENV:Envelope
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="">
      <SOAP-ENV:Body>
        <testString xmlns="
">
        </testString>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>



and it gives the correct result:
HTTP/1.1 200 OK
Connection: close
Date: Thu, 24 Apr 2008 08:28:49 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 375

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi="" xmlns:xsd="<A href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema
">
<soap:Body>
  <testStringResponse xmlns="">
    <testStringResult>Hello World</testStringResult>
  </testStringResponse>
</soap:Body></soap:Envelope>



Passing an empty array as parameter I get:

POST /DummyWS/Service1.asmx HTTP/1.1
User-Agent: Mac OS X; WebServicesCore.framework (1.0.0)
Host: 78.157.102.46:2234
Content-Type: text/xml
Soapaction: SOAPAction
Content-Length: 631
Connection: close

  <SOAP-ENV:Envelope
    xmlns:xsd="
http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="">
      <SOAP-ENV:Body>
        <m:testString xmlns:m="
">
          <parameters SOAP-ENC:arrayType="xsd:anyType[0]" 
xsi:type="SOAP-ENC:Array">
          </parameters>
        </m:testString>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>

The only difference for an empty dictionary is that <parameters> has 
xsi:type="SOAP-ENC:Dictionary"
Why is testString prepended by "m:" ?? Why is the namespace anonuri 
rather than
http://webservice.mydomain.com/? Why is Soapaction 
SOAPAction rather than http://webservice.mydomain.com/testString ??




Calling testString with an empty string gives:

POST /DummyWS/Service1.asmx HTTP/1.1
User-Agent: Mac OS X; WebServicesCore.framework (1.0.0)
Host: 78.157.102.46:2234
Content-Type: text/xml
Soapaction: SOAPAction
Content-Length: 579
Connection: close

  <SOAP-ENV:Envelope
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:SOAP-ENV="">
      <SOAP-ENV:Body>
        <m:testString xmlns:m="
">
          <parameters xsi:type="xsd:string"></parameters>
        </m:testString>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>




The response from the server is then:

HTTP/1.1 500 Internal Server Error
Connection: close
Date: Thu, 24 Apr 2008 08:19:42 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Content-Length: 876


<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsi="" xmlns:xsd="<A href="http://www.w3.org/2001/XMLSchema">http://www.w3.org/2001/XMLSchema
">
<soap:Body><soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: Server did 
not recognize the value of HTTP Header SOAPAction: SOAPAction.
    at 
System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
    at 
System
.Web
.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage 
message)
    at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
    at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type 
type, HttpContext context, HttpRequest request, HttpResponse response, 
Boolean&amp; abortProcessing)</faultstring>
<detail /></soap:Fault>
</soap:Body></soap:Envelope>


Cheers

   Nik

Related mailsAuthorDate
mlComplex data for webservices Niklas Saers Apr 20, 14:07
mlRe: Complex data for webservices Niklas Saers Apr 21, 13:45
mlRe: Complex data for webservices Niklas Saers Apr 21, 14:15
mlRe: Complex data for webservices Jeff LaMarche Apr 21, 15:30
mlRe: Complex data for webservices Niklas Saers Apr 23, 14:41
mlRe: Complex data for webservices Jeff LaMarche Apr 23, 16:25
mlRe: Complex data for webservices Niklas Saers Apr 24, 10:31
mlRe: Complex data for webservices Niklas Saers Apr 24, 10:40
mlRe: Complex data for webservices Niklas Saers Apr 25, 09:22