使用webservice时出错,内容类型"application/xop + xml"与预期类型"text/xml"不匹配

Rei*_*ica 36 .net c# webservice-client wcf-client

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

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

错误的详细信息如下,感谢您提供的任何帮助.

使用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--
--.
Run Code Online (Sandbox Code Playgroud)

如您所见,响应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--'.
Run Code Online (Sandbox Code Playgroud)

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

我可以设置任何选项,以便客户端对响应类型没有问题吗?我已经完成了一些Google搜索,但到目前为止,我发现的任何内容都没有帮助我.

Rei*_*ica 83

对于任何患有同样问题的人; 我找到了一种将Web服务作为服务引用(WCF)使用的解决方案.该BasicHttpBinding.MessageEncoding属性需要设置为"MTOM".

这是所需配置设置的片段:

<configuration>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding messageEncoding="Mtom">          
        </binding>
      </basicHttpBinding>
    </bindings>
  </system.serviceModel>
</configuration>
Run Code Online (Sandbox Code Playgroud)

编辑:如果您遇到与自定义绑定相同的问题,请参阅@robmzd答案.

我还没有找到一个解决方案,将其作为旧式Web Reference使用.


小智 14

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

  1. 通过从VS2010的主菜单中选择Tools-> WCF Service Configuration Editor来激活配置编辑器;
  2. 再次关闭它;
  3. 右键单击App.Config文件以查找新菜单项"编辑WCF配置";
  4. 点击绑定;
  5. 将MessageEncoding更改为Mtom;
  6. 保存.

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


rob*_*mzd 7

我有同样的问题,但与<customBinding>. 要修复它,您可以使用<mtomMessageEncoding>绑定下的单独配置节点来配置 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>
Run Code Online (Sandbox Code Playgroud)

  • 我已从我的答案中链接到您的答案,以帮助人们找到它。我没有将其复制到我的答案中,因为我不想窃取您的信用。:-) (3认同)

Ser*_*gio 5

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

string(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--
Run Code Online (Sandbox Code Playgroud)

如果你查看字符串的顶部,它有一个键值和来自服务器的其他人员,这使得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>
Run Code Online (Sandbox Code Playgroud)

类似地,在字符串的底部(在xml之后)出现相同的键

--uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962--
Run Code Online (Sandbox Code Playgroud)

因此,解决方案是尝试从xml文件的开头到开头以及从xml文件的末尾到字符串的末尾去掉字符串的一部分.我发现了一个非常好的脚本,帮助我在MTOM php客户端处理这个解决方案.但是,我的响应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;
    }

}
Run Code Online (Sandbox Code Playgroud)


Der*_*k W 5

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

BasicHttpBinding binding = new BasicHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Mtom;
Run Code Online (Sandbox Code Playgroud)

我也遇到了这个问题.我的客户端在启动时不断抛出此异常,直到我意识到忘记MessageEncoding在宿主应用程序中设置我的绑定属性,我才弄清楚原因.