1

我有一个 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告诉我它不能将 type 的对象分配给 typeClip[]的对象ClipList

所以我假设它将返回的数据反序列化为 aClip[]并且现在想要满足GetClipList 方法的返回类型(这将是ClipList)。

GetClipList()将代理中的返回值更改为Clip[]手动时,应用程序运行良好。但出于明显的原因,我想避免更改自动生成的类。

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

4

2 回答 2

1

在再次阅读了 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 中的集成服务导入似乎需要此定义。

于 2010-04-15T16:17:25.053 回答
1

我解决了结构数组的问题:

$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 在创建响应时存在错误,并为每个数组元素自动添加标签“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] => '') 
            ) ) )
于 2010-05-31T15:05:39.963 回答