tags:

views:

347

answers:

2

I have a SOAP service that returns an array of a complex type. The definition in NuSOAP in PHP looks like this:

// The type itself
$server->wsdl->addComplexType(
    "Clip",
    "complexType",
    "struct",
    "all",
    "",
    array(
      "Id" => array(
        "name" => "id",
        "type" => "xsd:int"
      )
      // ---snip---
    )
  );

// The type of the array
$server->wsdl->addComplexType(
    "ClipList",
    "complexType",
    "array",
    "sequence",
    "",
    array(
      "clip" => array(
        "name"      => "clip",
        "type"      => "tns:Clip",
        "minOccurs" => "0",
        "maxOccurs" => "unbounded"
      )
    ),
    array(),
    "tns:Clip"
  );

  // The service
  $server->register(
    "GetClipList",
    array(),
    array(
      "clips" => "tns:ClipList"
    ),
    "urn:MyNamespace",
    "urn:MyNamespace#GetClipList",
    "rpc",
    "encoded",
    "Retrieves a list of all clips."
  );

Now in my VisualStudio2010 C# project I added a new service based on the generated WSDL. VS created a proxy class for me to use which contains a class ClipList which has a single data member of type Clip[].

So far so good. Now when I call GetClipList() on my proxy I get a CommunicationException telling me that it cannot assign an object of type Clip[] to an object of type ClipList.

So I am assuming it deserialized the returned data into a Clip[] and now wants to satisfy the return type of the GetClipList method (which would be ClipList).

When changing the return value of GetClipList() in the proxy to Clip[] manually, the application runs fine. But I want to avoid changing the auto-generated class for obvious reasons.

So, why does it not instantiate a ClipList and fill the data member? Or alternatively, why doesn't VS generate the proxy class so that GetClipList directly returns a Clip[].

+1  A: 

After reading through parts of the W3C SOAP standard once more I came up with this definition for the Clip array:

$server->wsdl->addComplexType(
  "ArrayOfClip",
  "complexType",
  "array",
  "sequence",
  "SOAP-ENC:Array",
  array(),
  array(
    array(
      "ref"            => "SOAP-ENC:arrayType",
      "wsdl:arrayType" => "tns:Clip[]",
      "minOccurs"      => "0",
      "maxOccurs"      => "unbounded"
    )
  ),
  "tns:Clip"
);

I actually had a definition like that already commented out in my source as earlier tests with wsdl.exe and vscutil.exe didn't seem to agree with it. The integrated service import in VisualStudio however seems to require this definition.

gencha
A: 

I'm solved problem of array of structure:

$server->wsdl->addComplexType(
        'clsDispIds',
        'complexType',
        'struct',
        'sequence',
        '',
        array(
                'id_disp' => array('name' => 'id_disp', 'type' => 'xsd:int'),
                'id_loc' => array('name' => 'id_loc', 'type' => 'xsd:string')
        )
);

// array di clsDispIds
$server->wsdl->addComplexType(
    'arrclsDispIds',
    'complexType',
    'array',
    'sequence',
    '',
    array(
        'item' => array('name' => 'item', 'type'=>'tns:clsDispIds','minOccurs' => '0', 'maxOccurs' => 'unbounded')
    )
);    

$server->register( 
    'GetIdDispCollection',                  // nome operazione
    array('id'=>'xsd:int'),                 // input 
    array('return'=>'tns:arrclsDispIds'),   // output
    NAMESPACE, 
    true,
    'document',
    'literal',
    'restituisce tutti i dispositivi per il canale specificato',
    'http://schemas.xmlsoap.org/soap/encoding/'
);

nuSoap have a bug on the response creation and add automatically the tag "item" for each array element, therefore complexType have mandatory name "item"

This is my response that's correct deserialized by php, java & .net stdClass Object ( [return] => stdClass Object ( [item] => Array ( [0] => stdClass Object ( [id_disp] => 11718 [id_loc] => '') [1] => stdClass Object ( [id_disp] => 11722 [id_loc] => '') [2] => stdClass Object ( [id_disp] => 11723 [id_loc] => '') [3] => stdClass Object ( [id_disp] => 11724 [id_loc] => '') ) ) )

andrea