C#从SOAP错误解析数组类型

C#从SOAP错误解析数组类型,c#,php,soap,nusoap,C#,Php,Soap,Nusoap,我有一个SOAP服务,它返回一个复杂类型的数组。PHP中NuSOAP中的定义如下所示: // The type itself $server->wsdl->addComplexType( "Clip", "complexType", "struct", "all", "", array( "Id" => array( "name" => "id", "type" => "xs

我有一个SOAP服务,它返回一个复杂类型的数组。PHP中NuSOAP中的定义如下所示:

// 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."
  );
现在,在我的VisualStudio2010 C#项目中,我添加了一个基于生成的WSDL的新服务。VS为我创建了一个代理类,该类包含一个类
ClipList
,该类有一个类型为
Clip[]
的数据成员

到目前为止还不错。现在,当我在代理上调用
GetClipList()
时,我得到一个
CommunicationException
告诉我,它不能将
Clip[]类型的对象分配给
ClipList
类型的对象

因此,我假设它将返回的数据反序列化为
Clip[]
,现在希望满足
GetClipList
方法的返回类型(即
ClipList

手动将代理中的
GetClipList()
的返回值更改为
Clip[]
时,应用程序运行正常。但是我不想因为明显的原因而改变自动生成的类


那么,为什么它不实例化
ClipList
并填充数据成员呢?或者,为什么VS不生成代理类,以便
GetClipList
直接返回
Clip[]

在再次阅读W3C SOAP标准的部分内容后,我为Clip数组提出了以下定义:

$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"
);

事实上,我的源代码中已经注释了这样一个定义,因为之前使用wsdl.exe和vscutil.exe的测试似乎不同意它。然而,VisualStudio中的集成服务导入似乎需要此定义。

我解决了结构阵列的问题:

$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在创建响应时有一个bug,会自动为每个数组元素添加标记“item”,因此complexType必须具有“item”的强制名称

这是我的响应,通过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] => '') 
            ) ) )