【问题标题】:Error consuming webservice, content type "application/xop+xml" does not match expected type "text/xml"使用 Web 服务时出错,内容类型“application/xop+xml”与预期类型“text/xml”不匹配
【发布时间】:2012-05-16 19:02:36
【问题描述】:

在为我的公司购买的产品使用网络服务时,我遇到了一个奇怪的问题。该产品名为 Campaign Commander,由一家名为 Email Vision 的公司制造。我们正在尝试使用“Data Mass Update SOAP API”。

每当我尝试调用 web 服务上的任何方法时,调用实际上都会成功,但客户端在处理响应时失败并且我得到一个异常。

错误的详细信息如下,感谢你们提供的任何帮助。

使用 Web Reference 时出错(旧式 Web 服务客户端)

当使用该服务作为 Web 参考时,我会收到一个 InvalidOperationException,用于我拨打的任何电话,并带有以下消息:

Client found response content type of 'multipart/related; type="application/xop+xml"; boundary="uuid:170e63fa-183c-4b18-9364-c62ca545a6e0"; start="<root.message@cxf.apache.org>"; start-info="text/xml"', but expected 'text/xml'.
The request failed with the error message:
--

--uuid:170e63fa-183c-4b18-9364-c62ca545a6e0
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:openApiConnectionResponse xmlns:ns2="http://api.service.apibatchmember.emailvision.com/" xmlns:ns3="http://exceptions.service.apibatchmember.emailvision.com/">
      <return>DpKTe-9swUeOsxhHH9t-uLPeLyg-aa2xk3-aKe9oJ5S9Yymrnuf1FxYnzpaFojsQSkSCbJsZmrZ_d3v2-7Hj</return>
    </ns2:openApiConnectionResponse>
  </soap:Body>
</soap:Envelope>
--uuid:170e63fa-183c-4b18-9364-c62ca545a6e0--
--.

如您所见,响应SOAP信封看起来有效(这是有效响应且调用成功),但客户端似乎内容类型有问题并生成异常。

使用服务引用时出错(WCF 客户端)

当我将服务作为服务参考使用时,我会收到一个ProtocolException,用于我进行的任何调用,并带有以下消息:

The content type multipart/related; type="application/xop+xml"; boundary="uuid:af66440a-012e-4444-8814-895c843de5ec"; start="<root.message@cxf.apache.org>"; start-info="text/xml" of the response message does not match the content type of the binding (text/xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 648 bytes of the response were: '
--uuid:af66440a-012e-4444-8814-895c843de5ec
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:openApiConnectionResponse xmlns:ns2="http://api.service.apibatchmember.emailvision.com/" xmlns:ns3="http://exceptions.service.apibatchmember.emailvision.com/">
      <return>Dqaqb-MJ9V_eplZ8fPh4tdHUbxM-ZtuZsDG6GalAGZSfSzyxgtuuIxZc3aSsnhI4b0SCbJsZmrZ_d3v2-7G8</return>
    </ns2:openApiConnectionResponse>
  </soap:Body>
</soap:Envelope>
--uuid:af66440a-012e-4444-8814-895c843de5ec--'.

就像前面的例子一样;我们有一个有效的soap响应并且调用成功了,但是客户端似乎有内容类型的问题并且产生了一个异常。

我可以设置任何选项以使客户端不会对响应类型有问题吗?我进行了一些 Google 搜索,但到目前为止,我发现没有任何帮助。

【问题讨论】:

  • 我通过从一个 AppPool 更改为另一个(我的托管在 IIS 上)解决了这个问题,即使它们看起来是一样的。

标签: c# .net webservice-client wcf-client


【解决方案1】:

对于遇到同样问题的任何人;我找到了一种将 Web 服务用作服务参考 (WCF) 的解决方案。 BasicHttpBinding.MessageEncoding 属性需要设置为“Mtom”。

这是所需配置设置的 sn-p:

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding messageEncoding="Mtom">          
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>

编辑:如果您在自定义绑定方面遇到同样的问题,请参阅answer from @robmzd

我还没有找到将其用作旧式 Web 参考的解决方案。

【讨论】:

  • 这可能有助于旧的网络参考:
【解决方案2】:

经过几天的努力,我找到了一个非常简单的解决方案:

  1. 在VS2010的主菜单中选择Tools->WCF Service Configuration Editor来激活Configuration Editor;
  2. 再次关闭;
  3. 右击App.Config文件,找到一个新的菜单项“Edit WCF Configuration”;
  4. 点击绑定;
  5. 将MessageEncoding改为Mtom;
  6. 保存。

我希望这会对某人有所帮助。

【讨论】:

  • 通过编辑工具在我的配置中发现了很多c***。节省了我的工作时间!
【解决方案3】:

我遇到了同样的问题,但&lt;customBinding&gt;。要修复它,您可以使用绑定下的单独 &lt;mtomMessageEncoding&gt; 配置节点配置 Mtom 消息编码。

<configuration>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="MyServiceBinding">
          <mtomMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16" messageVersion="Soap12" writeEncoding="utf-8">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
          </mtomMessageEncoding>
        </binding>
      </customBinding>
    </bindings>
  </system.serviceModel>
</configuration>

【讨论】:

  • 我已将我的答案链接到您的答案,以帮助人们找到它。我没有将其复制到我的答案中,因为我不想窃取您的信用。 :-)
【解决方案4】:

如果您是自托管 WCF 服务,并且您通过 WCF 客户端使用该服务。您必须记住在主机中设置MessageEncoding 属性,如下所示:

BasicHttpBinding binding = new BasicHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Mtom;

我也遇到了这个问题。我的客户在启动时不断抛出这个异常,直到我意识到我忘记在主机应用程序中设置绑定MessageEncoding 属性之前我无法弄清楚为什么。

【讨论】:

    【解决方案5】:

    我在相同的功能和相同的公司遇到了完全相同的问题,我在 Google 上花了几个小时试图找到正确的答案。经过这么多的尝试,我终于得到了它。这是我所做的:以下字符串是来自 Email Vision 的响应,返回给我(我的主要目的是批量上传,但为了简单和测试,我换成了 getLastUpload)。

    字符串(2180)“

    --uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962
    Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
    Content-Transfer-Encoding: binary
    Content-ID: <root.message@cxf.apache.org>
    
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getLastUploadResponse xmlns:ns2="http://api.service.apibatchmember.emailvision.com/" xmlns:ns3="http://exceptions.service.apibatchmember.emailvision.com/"><return><id>254816</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254810</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254805</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254799</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254797</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254791</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254790</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254771</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254770</id><source>API_BATCH_MEMBER</source><status>ERROR</status></return><return><id>254759</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>254747</id><source>API_BATCH_MEMBER</source><status>DONE</status></return><return><id>253619</id><source>CCMD</source><status>DONE</status></return><return><id>238053</id><source>CCMD</source><status>DONE WITH ERROR(S)</status></return><return><id>216618</id><source>CCMD</source><status>DONE WITH ERROR(S)</status></return><return><id>200373</id><source>CCMD</source><status>DONE</status></return><return><id>200367</id><source>CCMD</source><status>DONE</status></return><return><id>195445</id><source>CCMD</source><status>DONE</status></return><return><id>194579</id><source>CCMD</source><status>DONE</status></return><return><id>194263</id><source>CCMD</source><status>DONE</status></return><return><id>193740</id><source>CCMD</source><status>DONE</status></return></ns2:getLastUploadResponse></soap:Body></soap:Envelope>
    --uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962--
    

    如果您查看字符串的顶部,它有一个键值和来自服务器的其他人员,这使得 SoapClient 类抛出异常“看起来我们没有 XML 文档”。尽管 xml 文档低于所有这些人员。

    --uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962
    Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
    Content-Transfer-Encoding: binary
    Content-ID: <root.message@cxf.apache.org>
    

    同样在字符串的底部(xml之后)出现相同的键

    --uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962--
    

    所以解决的办法就是尽量去掉xml文件开头到开头和xml文件结尾到字符串结尾的部分字符串。我在MTOM php client 找到了一个非常好的脚本,可以帮助我解决这个问题。但是,我的响应 xml 有点不同,所以我只是稍微修改了该脚本,这是我的版本。

    function upload_file_insert_via_soap_obj( $token, $csv_file )
    {
        try
        {
            $wsdl_loc = 'https:XXX/apibatchmember/services/BatchMemberService?wsdl';
    
            $soap_Object = new MTOMSoapClient( $wsdl_loc, array( 'cache_wsdl' => WSDL_CACHE_NONE, 'trace' => true ) );
    
            $parameters['token'] = $token;
            $parameters['insertUpload']['fileName'] = "insertMemberTest.txt";
            $parameters['insertUpload']['fileEncoding'] = "UTF-8";
            $parameters['insertUpload']['separator'] = ",";
            $parameters['insertUpload']['skipFirstLine'] = "false";
            $parameters['insertUpload']['autoMapping'] = "true"; 
    
            $parameters['file'] = file_get_contents( "insertMemberTest.txt" );
    
            $results = $soap_Object->uploadFileInsert( $parameters );
    
            $upload_id = $results->return;
    
            echo "<br/>upload_id: ".$upload_id;  
            return $upload_id;  
        }
        catch ( Exception $exception )
        {
            echo "EX REQUEST: " . $soap_Object->__getLastRequest() . "<br/>";
            echo "EX RESPONSE: " . $soap_Object->__getLastResponse() . "<br/>";
            echo "<br/>Response var dump: "; var_dump( $soap_Object->__getLastResponse() ); echo "<br/>";
    
            echo '<br/><br/> Exception: '.$exception->getMessage()."<br/>";
            var_dump( $exception );
        }
    }
    
    
    /**
    * This client extends the ususal SoapClient to handle mtom encoding. Due
    * to mtom encoding soap body has test apart from valid xml. This extension
    * remove the text and just keeps the response xml.
    */
    
    class MTOMSoapClient extends SoapClient 
    {
    
        public function __doRequest( $request, $location, $action, $version, $one_way = 0 ) 
        {
            $response = parent::__doRequest( $request, $location, $action, $version, $one_way );
            //if resposnse content type is mtom strip away everything but the xml.
            if ( strpos( $response, "Content-Type: application/xop+xml" ) !== false ) 
            {
                //not using stristr function twice because not supported in php 5.2 as shown below
                //$response = stristr(stristr($response, "<s:"), "</s:Envelope>", true) . "</s:Envelope>";
                $tempstr = stristr( $response, "<soap:" );
                $response = substr( $tempstr, 0, strpos( $tempstr, "</soap:Envelope>" ) ) . "</soap:Envelope>";
            }
            //log_message($response);
            return $response;
        }
    
    }
    

    【讨论】:

    • 请提供解决方案url的链接
    【解决方案6】:

    我刚刚遇到了这个问题,因为 configSections> 不是 configuration> 中的第一个元素。

    【讨论】:

      【解决方案7】:

      我不确定这是否适合放置它,但我很难让我的 Windows 服务连接到 WSDL(使用自动生成的 Web 引用)。

      我在这里遇到了与原始海报相同的错误。由于我没有使用 WCF,因此 app.config 对我不起作用并导致我的服务无法启动。我确实在 MSDN 上找到了 AjayChigurupati 声明要更改的帖子

      public partial class WsdlService : System.Web.Services.Protocols.SoapHttpClientProtocol {...}

      public partial class WsdlService : Microsoft.Web.Services3.WebServicesClientProtocol {...}

      (确保将Microsoft.Web.Services3 引用添加到您的项目中)

      现在我们可以访问布尔属性RequireMtom,你可以像这样包围你的调用函数:

          public DownloadResponse downloadDataFile([System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] DownloadRequest Request) {
              RequireMtom = true; // ADDED
              object[] results = this.Invoke("downloadDataFile", new object[] {
                          Request});
              RequireMtom = false; // ADDED
              return ((DownloadResponse)(results[0]));
          }
      

      希望这可以帮助将来遇到同样问题的其他人。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 2015-03-02
        • 2020-01-22
        • 1970-01-01
        • 1970-01-01
        • 2017-07-14
        相关资源
        最近更新 更多