views:

246

answers:

2

I am trying to pass data to an ASP.NET based Web Service using the WSDL file containing the below:

<s:element minOccurs="1" maxOccurs="1" name="ContactId" nillable="true" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="GenderId" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="EthnicityId" type="s:int"/>
<s:element minOccurs="0" maxOccurs="1" name="Title" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Initials" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Honours" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="FirstName" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Surname" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Salutation" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Position" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Department" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Organisation" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="AccessRequirements" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="DietaryNeeds" type="s:string"/>
<s:element minOccurs="1" maxOccurs="1" name="BirthDate" nillable="true" type="s:dateTime"/>
<s:element minOccurs="1" maxOccurs="1" name="IsNewContact" type="s:boolean"/>
<s:element minOccurs="1" maxOccurs="1" name="HoldingId" nillable="true" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="WebId" nillable="true" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="RecruitedId" type="s:int"/>

The data I am passing to the above in PHP is:

'ContactId'=>NULL
'GenderId'=>1
'EthnicityId'=>1
'Title'=>'Mr'
'Initials'=>'JB'
'Honours'=>'Degree'
'FirstName'=>'Joe'
'Surname'=>'Bloggs'
'Salutation'=>'Dear Joe Bloggs'
'Position'=>'Manager'
'Department'=>'Executive'
'Organisation'=>'Organisation'
'AccessRequirements'=>'None'
'DietaryNeeds'=>'None'
'BirthDate'=>NULL
'IsNewContact'=>TRUE
'HoldingId'=>NULL
'WebId'=>NULL
'RecruitedId'=>-1

The error I get back when passing data to the Web Service is:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
<soap:Body>
<soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>Server was unable to process request. ---&gt; Object reference not set to an instance of an object.</faultstring>
<detail />
</soap:Fault>
</soap:Body>
</soap:Envelope>

This is the code I am using to call the Web Service:

$url='http://domain.com/webservice.asmx?wsdl';
$client = new SoapClient($url,array(
"trace"      => 1,
"exceptions" => 1));
$params = array('ContactId'=>$contactid,
                'GenderId'=>$gender,
                'EthnicityId'=>$ethnicity,
                'Title'=>$title,
                'Initials'=>$initials,
                'Honours'=>$honours,
                'FirstName'=>$firstname,
                'Surname'=>$surname,
                'Salutation'=>$salutation,
                'Department'=>$department,
                'Organisation'=>$organisation,
                'AccessRequirements'=>$accessreq,
                'DietaryNeeds'=>$dietary,
                'BirthDate'=>$birthdate,
                'IsNewContact'=>$isnew,
                'HoldingId'=>$holdingid,
                'WebId'=>$webid,
                'RecruitedId'=>$recruitedid);

try {
        $client->PersonalDetails_Update((object)$params);
    } catch (SoapFault $e){
        var_dump($e, $client->__getLastRequest());
    }   
print htmlentities($client->__getLastResponse());

I have asked the Web Service provider to allow HoldID to be 'nillable'. I have also tried to isolate the issue to birthDate as I had a hunch that it might be the birthDate value wasn't set correctly, so that's nillable too. Still getting the problem though.

Here is the Fault String that is being outputted when I run the code:

  ["faultstring"]=>
  string(96) "Server was unable to process request. ---> Object reference not set to an instance of an object."
  ["faultcode"]=>
  string(11) "soap:Server"
  ["detail"]=>
  string(0) ""
A: 

To debug, set trace to true, and inspect your request.

<?php
$client = new SoapClient($yourwsdl,array('trace'=>true));
try {
     $client->somefunc($args);
} catch (SoapFault $e){
     var_dump($e, $client->__getLastRequest());
}
?>

If you see a lot of Key/Value entries, try this one:

$client->somefunc((object)$args);//cast arguments to an object.

If you have already done that, it's a matter of examining the wsdl some more, and possibly more documentation of what it should comply to.

On a side note: storing ethnicity? Really? Quaint.

Wrikken
Thanks for this. The code I am getting back when I view source is:object(SoapFault)#3 (9) { ["message:protected"]=> string(96) "Server was unable to process request. ---> Object reference not set to an instance of an object." ["string:private"]=> string(0) "" ["code:protected"]=> int(0) ["file:protected"]=> string(57) "domain/index.php" ["line:protected"]=> int(47) ["trace:private"]=> array(2) {In response to your side note - I'm just the dev following instructions.
baswoni
Could the problem be with the way I am setting the birthdate value? It requests it in dateTime format. I've tried passing it as a string and integer: 1980-01-25 00:00:00 but not sure if it's correct. When pulling data out of the Web Service, birthdate comes out as 1934-04-07T00:00:00
baswoni
Could be (although the error would possibly be different, but I don't know the webservice in question). ISO8601 is kind of default: `date('c',$timestamp);` I'd sooner say it was an invalid 'HoldingId' though
Wrikken
Another commenter pointed out it's likely to be HoldingId. I've contacted the Web Service provider about this as they told me to set it to 0 at first then NULL as it's an auto incrementing value in the database.
baswoni
Erm, what now? The whole purpose of a webservice is that YOU don't need to handle / think about that stuff. And if it needs to be set to null, they need to declare that possible in their wsdl.
Wrikken
I agree. But I'm working with a company that manages our CRM system which is closed and they won't provide documentation. So we commissioned a Web Service to be built to allow us access to the data. They're new to this and so am I so, lots of debugging happening.
baswoni
Ah, so it's not really a finished product yet, then all is forgiven of course :)
Wrikken
A: 

ASP.NET SOAP services expect the parameters to be passed as an object. For example:

$client = new SoapClient( $wsdlFile, $params );

$args->ContactId = NULL;   
$args->GenderId = 1;   
$args->EthnicityId = 1;   
$args->Title = 'Mr';   
$args->Initials = 'JB';   
$args->Honours = 'Degree';   
$args->FirstName = 'Joe';   
$args->Surname = 'Bloggs';
$args->Salutation = 'Dear Joe Bloggs';   
$args->Position = 'Manager';   
$args->Department = 'Executive';   
$args->Organisation = 'Organisation';   
$args->AccessRequirements = 'None';   
$args->DietaryNeeds = 'None';   
$args->BirthDate = '1980-01-25 00:00:00';   
$args->IsNewContact = TRUE;   
$args->HoldingId = NULL;   
$args->WebId = NULL;   
$args->RecruitedId = -1;

$return = $client->DoSomething( $args );
Jon Benedicto
Thanks for this. I've given this a try, but I get: Fatal error: Uncaught SoapFault exception: [soap:Server] Server was unable to process request. ---> Object reference not set to an instance of an object. in domain/index.php:48 Stack trace: #0 [internal function]: SoapClient->__call('PersonalDetails...', Array) #1 domain/index.php(48): SoapClient->PersonalDetails_Update(Object(stdClass)) #2 {main} thrown in domain/index.php on line 48
baswoni