Использование apachesoap: сопоставление сложных типов данных в веб-сервисе с использованием .net - PullRequest
3 голосов
/ 15 июля 2009

У меня запрограммирован веб-сервис на Coldfusion, который я пытаюсь использовать с помощью c # .net.

Определенные веб-сервисы возвращают структуру coldfusion (набор элементов с ключом и значением), которая предоставляется веб-сервисом как сложный объект типа apachesoap: Map

<wsdl:message name="getDetailResponse">
    <wsdl:part name="getDetailReturn" type="apachesoap:Map"/>
</wsdl:message>

Сложный тип правильно объявлен в файле WSDL, автоматически сгенерированном coldfusion

<schema targetNamespace="http://xml.apache.org/xml-soap">
    <import namespace="http://webservice.templates"/>
    <import namespace="http://rpc.xml.coldfusion"/>
    <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/>
    <complexType name="mapItem">
        <sequence>
            <element name="key" nillable="true" type="xsd:anyType"/>
            <element name="value" nillable="true" type="xsd:anyType"/>
        </sequence>
    </complexType>

    <complexType name="Map">

        <sequence>
            <element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/>
        </sequence>
    </complexType>
</schema>

При попытке использовать это, используя следующий код c #:

theWebservice.theWebservice myWS = new theWebservice.theWebservice();
theWebservice.Map myMap = myWS.searchForRecord("some record data");

if (myMap.item == null) {
    Response.Write("myMap.item is null");
}

Код компилируется нормально, но отображает «myMap.item is null», а не является объектом с парой ключ и значение.

Проверка с помощью отладчика показывает, что у myMap есть два дочерних элемента и itemField типа theWebservice.mapItem [] и оба значения null.

Я видел другие сообщения на форуме с похожей проблемой, но без ответов. Кто-нибудь знает, как я могу правильно использовать службу, не меняя веб-службы для использования простых типов?

Отредактировано для предоставления дополнительной информации

Что касается вопросов Джона Сондерса, я использую .NET Framework 3.5 в Visual Web Developer 2008. Веб-сервис был включен в качестве веб-ссылки, а ответный SOAP-код предоставлен ниже (из soapUI):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ns1:getDetailResponse soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://DefaultNamespace">
            <getDetailReturn xsi:type="ns2:Map" xmlns:ns2="http://xml.apache.org/xml-soap">
                <item xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
                    <key xsi:type="soapenc:string">a</key>
                    <value xsi:type="soapenc:string">1</value>
                </item>
                <item>
                    <key xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">b</key>
                    <value xsi:type="soapenc:string" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">2</value>
                </item>
            </getDetailReturn>
        </ns1:getDetailResponse>
    </soapenv:Body>
</soapenv:Envelope>

1 Ответ

2 голосов
/ 22 февраля 2010

Вы всегда можете использовать веб-сервис coldfusion без использования встроенных сервисов .NET. Это потребует, чтобы вы вручную проанализировали ответ, но эй, это XML, так что это не так уж плохо.

Допустим, у вас есть этот веб-сервис:

<cfcomponent>
  <cffunction name="GetStruct" access="remote" returntype="struct" output="no">
        <cfscript>
           var struct = StructNew();
           struct.foo = "bar";
           struct.baz = 2;
           struct.Stooges = StructNew();
           struct.Stooges.Larry = 1;
           struct.Stooges.Moe = "Hi Mom";
           struct.Stooges.Curley = "Not Shemp"; 
        </cfscript>

    <cfreturn struct>
  </cffunction>
</cfcomponent>

настройте ваш запрос в .Net так:

var request = WebRequest.Create("http://localhost/test.cfc?method=GetStruct");
var response = request.GetResponse();
String content;
using (var reader = new StreamReader(response.GetResponseStream()))
{
  content = reader.ReadToEnd();
}

Контент, который вы получите, будет в виде пакета wddx:

<wddxPacket version="1.0">
    <header /> 
    <data>
        <struct>
            <var name="BAZ">
                <string>2</string> 
            </var>
            <var name="STOOGES">
                <struct>
                    <var name="MOE">
                      <string>Hi Mom</string> 
                    </var>
                    <var name="CURLEY">
                      <string>Not Shemp</string> 
                    </var>
                    <var name="LARRY">
                      <string>1</string> 
                    </var>
                </struct>
          </var>
          <var name="FOO">
            <string>bar</string> 
          </var>
        </struct>
    </data>
</wddxPacket>

конечно, еще лучшим решением может быть просто вернуть XML для начала с

P.S. Вы также можете заставить coldfusion сериализовать структуру как JSON с помощью returnformat = "json" в теге cffunction.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...