开发者

C# incorrectly parsing array type from SOAP

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->ad开发者_如何学PythondComplexType(
    "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[].


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.


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] => '') 
            ) ) )
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜