【问题标题】:Debug C# webservice client调试 C# web 服务客户端
【发布时间】:2010-07-28 08:35:06
【问题描述】:

我在使用 C# Web 服务客户端调用 ASP.NET 2.0 Web 服务时遇到了一个奇怪的问题。 该服务是一个简单的产品搜索并返回与搜索词匹配的产品数组 - 请参阅下面 WSDL 文件的相关部分。
我的 C# 客户端只是通过在 VS2010(非 WCF)中添加 Web 引用生成的,为了进行比较,我使用的是 Axis 1.4 Java 客户端。
在 C# 和 Java 客户端中使用相同的搜索参数,调用返回 50 个产品,但在 C# 客户端中,结果数组的长度为 1,而 Java 客户端显示正确的 50 个元素。

我正在寻找如何定位问题的建议 - 我尝试了以下方法:

  • 使用 TCP/IP 监视器比较 Web 服务返回的 XML:XML 看起来与 C# 与 Java 相同,并且包含 50 个产品
  • 使用 netcat 比较 HTTP 参数:C# 默认为 HTTP 1.1,而 Axis 1.4 使用 HTTP 1.0,但将 C# 客户端也更改为使用 HTTP 1.0 并没有任何改变
  • 尝试 SOAP 1.2 而不是 SOAP 1.1:无效
  • 尝试使用 HttpGetProtocol、HttpPostProtocol 代替 Soap

非常感谢任何建议。


编辑:完整的 WSDL 和生成的代码 (Reference.cs) 可以在这里找到:
http://timmay.dk/Reference.txt
http://timmay.dk/Wsdl.txt

简化的 WSDL 部分:

      <s:element name="Search">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="SearchTerm" type="s:string" />
        <s:element minOccurs="0" maxOccurs="1" name="StartFrom" type="s:string" />
        <s:element minOccurs="0" maxOccurs="1" name="NumberToBeReturned" type="s:string" />
      </s:sequence>
    </s:complexType>
  </s:element>
  <s:element name="SearchResponse">
    <s:complexType>
      <s:sequence>
        <s:element minOccurs="0" maxOccurs="1" name="SearchResult" type="tns:SearchResult" />
      </s:sequence>
    </s:complexType>
  </s:element>
  <s:complexType name="SearchResult">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="Products" type="tns:ArrayOfResponseProduct" />
    </s:sequence>
  </s:complexType>
  <s:complexType name="ArrayOfResponseProduct">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="unbounded" name="ResponseProduct" nillable="true" type="tns:ResponseProduct" />
    </s:sequence>
  </s:complexType>
  <s:complexType name="ResponseProduct">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="Fields" type="tns:ArrayOfResponseField" />
    </s:sequence>
    <s:attribute name="id" type="s:string" />
  </s:complexType>

【问题讨论】:

  • C# 客户端如何用 1 个数组元素返回 50 个产品?
  • 数组 应该 的长度为 50 但长度为 1。通过查看 TCP/IP 监视器中的 XML,我可以看到服务返回的所有 50 个产品- 解析结果是问题。
  • 由于显而易见的答案对您没有帮助,我们需要查看您生成的代码,甚至是一个包含错误的小型完整工作示例(但这可能有点困难情况)。
  • @Abel:我在生成的代码和 WSDL 中添加了外部链接——也许它在某个地方触发了一个想法。提供的 sn-p 已经简化了一点。
  • 有人对如何调试生成的客户端的“解析响应 XML”部分有建议吗?

标签: c# .net web-services asmx webservice-client


【解决方案1】:

我从 WSDL 中得知 maxOccurs 是 1。所以看来您确实应该只收到一个 SearchResult。但是,该结果本身应该包含一个 ArrayOfReponseProduct 类型的对象,其中包含无限数量的 `ResponseProduct 项。也许你看的不够深?

您是否尝试使用变量检查器(本地、自动、即时等)检查调试器内部?对象是有类型的还是无类型的,在这种情况下,您可能需要先对其进行强制转换才能看到内容?

【讨论】:

  • 这是正确的 - 您收到 1 个 SearchResult 对象,并且该对象具有 ArrayOfResponseProduct(生成代码中的 SearchResult.Products)。这个在 C# 代码中的长度为 1,在 Java 代码中的长度为 50。调试器显示 1 项,提示数组的 Length 属性。
  • @Tim:我可以假设您已经检查了该项目是否不是另一个级别的数组或枚举器,正如您的 WSDL 所建议的那样?
  • 是的,一个项目只是一个“ResponseProduct”,它由一组属性组成。 XML 如下所示: ... - 每个 ResponseProduct 项都有一个字段列表。我收到的 Products 数组中的单个条目具有“id”1330601,就像根据 XML 一样。调试 Java 客户端会产生相同的结构,只是 Products 数组中有 50 个项目。
【解决方案2】:

原来罪魁祸首是返回值的类型——响应字段

< s:complexType name="ResponseField">
    <s:sequence>
      <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string" />
      <s:element minOccurs="0" maxOccurs="1" name="Value">
        <s:complexType>
          <s:sequence>
            <s:element ref="s:schema" />
            <s:any />
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:sequence>
  </s:complexType>

这是 pr 默认转换为 System.Data.DataSet - 将其更改为简单的字符串解决了问题。在这种情况下,似乎解组失败。

【讨论】:

    猜你喜欢
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多