消费ApacheSOAP中:使用.NET映射复杂数据类型的web服务数据类型、复杂、ApacheSOAP、NET

2023-09-03 23:29:42 作者:空虚`永远填不满

我在其中的ColdFusion我试图使用C#.NET消耗编程的web服务。

在特定web服务返回的ColdFusion结构(带键和值项的集合),这是由web服务类型ApacheSOAP中的一个复杂的对象暴露:地图

 < WSDL:消息名称=getDetailResponse>
    < WSDL:一部分NAME =getDetailReturnTYPE =ApacheSOAP中:图/>
< / WSDL:消息>
 

复杂类型是否正确由ColdFusion的自动生成的WSDL文件中声明

 <架构的targetNamespace =htt​​p://xml.apache.org/xml-soap>
    <进口命名空间=HTTP://webservice.templates/>
    <进口命名空间=HTTP://rpc.xml.coldfusion/>
    <进口命名空间=htt​​p://schemas.xmlsoap.org/soap/encoding//>
    <复杂类型名称=mapItem>
        <序列>
            <元素名称=关键的nillable =真TYPE =XSD:anyType的/>
            <元素名称=值的nillable =真TYPE =XSD:anyType的/>
        < /序列>
    < /复杂类型>

    <复杂类型名称=地图>

        <序列>
            <元素的maxOccurs =无界的minOccurs =0NA​​ME =项目式=ApacheSOAP中:mapItem/>
        < /序列>
    < /复杂类型>
< /架构>
 

在尝试使用下面的C#code消耗这样的:

  theWebservice.theWebservice myWS =新theWebservice.theWebservice();
theWebservice.Map MYMAP = myWS.searchForRecord(一些记录数据);

如果(myMap.item == NULL){
    回复于(myMap.item为空);
}
 
CBNData 饿了么 2016在线外卖消费大数据洞察

在code编译罚款,但显示myMap.item为空,而不是作为一个对象键和值对。

检查与调试器显示MYMAP有两个孩子的项目和itemField两种类型的theWebservice.mapItem []和两个null值。

我见过的其他论坛的帖子有一个类似的问题,但没有答复,没有人知道我可以正确地使用该服务,而无需改变Web服务使用的只是简单的类型?

编辑以提供更多信息

按照约翰·桑德斯'的问题

,我在Visual Web Developer中2008使用.NET Framework 3.5的Web服务被纳入作为一个Web引用和响应SOAP code提供如下(从soapUI的):

 < soapenv:信封的xmlns:soapenv =htt​​p://schemas.xmlsoap.org/soap/envelope/的xmlns:XSD =HTTP://www.w3。组织/ 2001 / XML模式的xmlns:XSI =http://www.w3.org/2001/XMLSchema-instance>
    < soapenv:身体与GT;
        < NS1:getDetailResponse soapenv:encodingStyle的=htt​​p://schemas.xmlsoap.org/soap/encoding/的xmlns:NS1 =HTTP:// DefaultNamespace的>
            < getDetailReturn的xsi:type =NS2:地图的xmlns:NS2 =htt​​p://xml.apache.org/xml-soap>
                <项目的xmlns:SOAPENC =htt​​p://schemas.xmlsoap.org/soap/encoding/>
                    <关键的xsi:type =SOAPENC:字符串>在< /键>
                    <值的xsi:type =SOAPENC:字符串> 1< /值GT;
                < /项目>
                <项目>
                    <关键的xsi:type =SOAPENC:字符串的xmlns:SOAPENC =htt​​p://schemas.xmlsoap.org/soap/encoding/> B< /键>
                    <值的xsi:type =SOAPENC:字符串的xmlns:SOAPENC =htt​​p://schemas.xmlsoap.org/soap/encoding/> 2'; /值GT;
                < /项目>
            < / getDetailReturn>
        < / NS1:getDetailResponse>
    < / soapenv:身体与GT;
< / soapenv:信封>
 

解决方案

您可以随时消耗的ColdFusion Web服务,而无需使用内置的服务.NETs。这将需要您手动解析响应,但是,嘿,这是XML,所以它不是那么糟糕。

可以说,你有这样的Web服务:

 < CFCOMPONENT>
  < cffunction名=GetStruct访问=远程的返回类型=结构输出=没有>
        < CFSCRIPT>
           变种结构= StructNew();
           struct.foo =酒吧;
           struct.baz = 2;
           struct.Stooges = StructNew();
           struct.Stooges.Larry = 1;
           struct.Stooges.Moe =喜妈妈;
           struct.Stooges.Curley =未Shemp;
        < / CFSCRIPT>

    < cfreturn结构>
  < / cffunction>
< / CFCOMPONENT>
 

设置你的要求在.net中是这样的:

  VAR请求= WebRequest.Create(HTTP://localhost/test.cfc方法= GetStruct);
变种响应= request.GetResponse();
字符串的内容;
使用(VAR读卡器=新的StreamReader(response.GetResponseStream()))
{
  含量= reader.ReadToEnd();
}
 

你得到的内容是这样的一个WDDX数据包:

 < wddxPacket版本=1.0>
    <头/>
    <数据>
        <结构>
            < VAR名称=BAZ>
                &其中;串→2&其中; /串GT;
            < / VAR>
            < VAR名称=臭皮匠>
                <结构>
                    < VAR名称=教育部>
                      <字符串>喜妈妈< /串>
                    < / VAR>
                    < VAR名称=CURLEY>
                      <字符串>不Shemp< /串>
                    < / VAR>
                    < VAR名称=拉里>
                      <字符串> 1< /串>
                    < / VAR>
                < /结构>
          < / VAR>
          < VAR名称=富与GT;
            <字符串>巴≤; /串>
          < / VAR>
        < /结构>
    < /数据>
< / wddxPacket>
 

当然,

的甚至更好的解决方案可能是只返回XML开始与

P.S。您还可以强制ColdFusion的与returnformat上cffunction标签序列化结构作为JSON =json的。

I have a webservice programmed in coldfusion which I'm attempting to consume using c#.net.

The particular webservices returns a coldfusion structure (a collection of items with a key and a value) which is exposed by the webservice as a complex object of type apachesoap:Map

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

The complex type is correctly declared in the WSDL file automatically generated by 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>

When attempting to consume this using the following c# code:

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

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

The code compiles fine but displays the "myMap.item is null" rather than being an object with a key and value pair.

Inspection with the debugger shows myMap has two children item and itemField both of type theWebservice.mapItem[] and both of value null.

I've seen other forum posts with a similar issue but no replies, does anyone know how I can consume the service correctly without having to alter the webservice to use just simple types?

Edited to provide more information

As per John Saunders' questions, I'm using .NET Framework 3.5 in Visual Web Developer 2008. the webservice was included as a web reference and the response SOAP code is provided below (from 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>

解决方案

You can always consume the coldfusion web service without using .NETs built in services. This would require that you manually parse the response, but hey, It's XML so it's not that bad.

Lets say you have this web service:

<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>

set up your request in .Net like this:

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();
}

The content you get back will be a wddx packet like this:

<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>

of course the even better solution might be to just return XML to begin with

P.S. You can also force coldfusion to serialize the struct as JSON with returnformat="json" on the cffunction tag.