2010-04-14 8 views
1

У меня есть служба SOAP, которая возвращает массив сложного типа. Определение в NuSOAP в PHP выглядит следующим образом:C# неправильный синтаксический анализ массива из SOAP

// 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[].

ответ

1

После прочтения частей стандарта W3C SOAP еще раз я придумал это определение для массива клипа:

$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, похоже, требует этого определения.

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 есть ошибка о создании ответа и добавить автоматически тег «элемент» для каждого элемента массива, поэтому ComplexType имеют обязательное название «пункт»

Это мой ответ, что это правильно десериализации с помощью 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] => '') 
      )))