使用apache soap:使用.net在Web服务中映射复杂数据类型

时间:2009-07-15 16:40:05

标签: .net web-services soap

我有一个用coldfusion编写的web服务,我试图用c#.net来消费。

特定的webservices返回一个coldfusion结构(带有键和值的项集合),它由webservice作为apachesoap类型的复杂对象公开:Map

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

复杂类型在coldfusion自动生成的WSDL文件中正确声明

<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为null”,而不是具有键和值对的对象。

使用调试器进行检查显示myMap有两个子项和itemField,类型为Webservice.mapItem [],值均为null。

我看过其他论坛帖子有类似问题但没有回复,有没有人知道如何正确使用服务而不必改变webservice只使用简单类型?

已修改以提供更多信息

根据John Saunders的提问,我在Visual Web Developer 2008中使用.NET Framework 3.5.webservice作为Web引用包含在内,响应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 个答案:

答案 0 :(得分:2)

您始终可以在不使用.NET内置服务的情况下使用coldfusion Web服务。这需要您手动解析响应,但是,它是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,并在cffunction标记上使用returnformat =“json”。