41

在为我公司购买的产品使用网络服务时,我遇到了一个奇怪的问题。该产品名为 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--
--.

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

使用服务参考(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 搜索,但到目前为止,我发现的任何内容都没有帮助我。

4

7 回答 7

89

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

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

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

编辑:如果您对自定义绑定有同样的问题,请参阅@robmzd 的答案

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

于 2012-05-08T11:01:24.230 回答
15

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

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

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

于 2014-06-26T16:06:21.553 回答
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>
于 2015-12-18T08:28:00.407 回答
6

如果您正在自托管 WCF 服务,并且您正在使用 WCF 客户端使用该服务。您必须记住MessageEncoding像这样在主机中设置属性:

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

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

于 2013-05-24T13:56:18.837 回答
5

I got exactly the same problem with the same function and the same company and I spend a couple of hours on Google trying to find the right answer. After so many trials I finally got it. Here is what I did: The following string was the response that functions from Email Vision where returning me (My main purpose was Mass Upload but I swap to getLastUpload for simplicity and testing).

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

If you look at the top of the string it has a key value and other staff from the server which made the SoapClient class to throw an exception "looks like we got no XML document". Eventhough the xml document was below all this staff.

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

Similarly at the bottom of the string (after the xml) the same key appears

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

So the solution was to try to get rid of the part of the string from the beginning to the start of the xml file and from the end of the xml file to the end of the string. I found a very good script that helped me to approach this solution here MTOM php client. However, my response xml was a bit different so I just modified that script a little bit and here is my version.

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

}
于 2012-12-10T04:47:46.610 回答
0

I just got this problem because <configSections> was not the first element in <configuration>.

于 2015-02-09T05:45:26.740 回答
0

我不确定这是否是放置此内容的合适位置,但我很难让我的 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]));
    }

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

于 2017-05-31T17:05:41.497 回答