【问题标题】:Consuming apachesoap:Map complex datatype in webservice using .net使用 apache soap:使用 .net 在 Web 服务中映射复杂数据类型
【发布时间】:2009-07-15 16:40:04
【问题描述】:

我有一个用coldfusion 编写的web 服务,我正在尝试使用c#.net 来使用它。

特定的 Web 服务返回一个冷融合结构(具有键和值的项的集合),该结构由 Web 服务公开为 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 is null”,而不是具有键值对的对象。

使用调试器检查显示 myMap 有两个子项 item 和 itemField 的类型均为 theWebservice.mapItem[] 且均为 null。

我看到其他论坛帖子有类似问题但没有回复,有人知道我如何正确使用服务而无需更改网络服务以仅使用简单类型吗?

已编辑以提供更多信息

根据 John Saunders 的问题,我在 Visual Web Developer 2008 中使用 .NET Framework 3.5。该 Web 服务作为 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>

【问题讨论】:

  • 请发布正在发送的 XML。这将是一个命名空间问题。
  • 另外,您使用的是“添加 Web 引用”还是“添加服务引用”,您使用的是什么版本的 .NET 和 Visual Studio?
  • 我已编辑问题以提供更多信息 - 如果您需要更多详细信息,请告诉我。谢谢。
  • 你有没有找到解决这个问题的方法?我刚刚遇到了同样的事情。我尝试使用 Add Web Reference 和 Add Service Reference,两者的结果相同。您提到了将 Web 服务更改为使用简单类型 - 您为使其正常工作做了哪些更改?
  • 嗨,Richard,不,我还没有找到适用于 Coldfusion 结构的解决方案。我们唯一的选择是停止使用结构并改用字符串数据类型。

标签: .net web-services soap


【解决方案1】:

您始终可以在不使用 .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 开头

附:您还可以强制 Coldfusion 将结构序列化为 JSON,并在 cffunction 标记上使用 returnformat="json"。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多