C# 使用 Web 服务时出错,内容类型“application/xop+xml”与预期类型“text/xml”不匹配
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10496186/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error consuming webservice, content type "application/xop+xml" does not match expected type "text/xml"
提问by Doctor Jones
I'm having a weird issue when consuming a webservice for a product that my company has bought. The product is called Campaign Commander and it's made by a company called Email Vision. We're trying to use the "Data Mass Update SOAP API".
在为我公司购买的产品使用网络服务时,我遇到了一个奇怪的问题。该产品名为 Campaign Commander,由一家名为 Email Vision 的公司制造。我们正在尝试使用“数据批量更新 SOAP API”。
Whenever I try to call any of the methods on the webservice, the call actually succeeds but the client fails when processing the response and I get an exception.
每当我尝试调用 Web 服务上的任何方法时,调用实际上都会成功,但客户端在处理响应时失败,并且出现异常。
The details of the errors are below, thanks for any help you guys can offer.
错误的详细信息如下,感谢你们提供的任何帮助。
Error using Web Reference (old style webservice client)
使用 Web 参考时出错(旧式 Web 服务客户端)
When consume the service as a Web Reference I get an InvalidOperationExceptionfor any call that I make, with the following message:
当使用该服务作为 Web 参考时,我会收到InvalidOperationException任何我拨打的电话,并显示以下消息:
Client found response content type of 'multipart/related; type="application/xop+xml"; boundary="uuid:170e63fa-183c-4b18-9364-c62ca545a6e0"; start="<[email protected]>"; 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: <[email protected]>
<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--
--.
As you can see, the response soap envelope looks valid (this is a valid response and the call succeeded), but the client seems to have a problem with the content type and generates an exception.
如您所见,响应soap信封看起来有效(这是一个有效的响应并且调用成功),但客户端似乎对内容类型有问题并生成异常。
Error using Service Reference (WCF client)
使用服务引用时出错(WCF 客户端)
When I consume the service as a Service Reference I get a ProtocolExceptionfor any call that I make, with the following message:
当我将服务作为服务参考使用时,我会收到ProtocolException任何调用的响应,并显示以下消息:
The content type multipart/related; type="application/xop+xml"; boundary="uuid:af66440a-012e-4444-8814-895c843de5ec"; start="<[email protected]>"; 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: <[email protected]>
<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--'.
Just like with the previous example; we've got a valid soap response and the call was successful, but the client seems to have a problem with the content type and has generated an exception.
就像前面的例子一样;我们得到了一个有效的soap 响应并且调用成功了,但是客户端的内容类型似乎有问题并且产生了一个异常。
Are there any options I can set so the client doesn't have a problem with the response type? I've done some Google searches, but nothing that I've found has helped me so far.
是否有任何我可以设置的选项,以便客户端对响应类型没有问题?我已经做了一些谷歌搜索,但到目前为止我发现的任何内容都没有帮助我。
采纳答案by Doctor Jones
For anyone suffering from the same problem; I've found a solution for consuming the web service as a Service Reference (WCF). The BasicHttpBinding.MessageEncodingproperty needs setting to "Mtom".
对于任何遭受同样问题的人;我找到了将 Web 服务作为服务引用 (WCF) 使用的解决方案。该BasicHttpBinding.MessageEncoding属性需要设置为“MTOM”。
Here's a snippet of the required config setting:
这是所需配置设置的片段:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding messageEncoding="Mtom">
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
Edit: If you are having the same issue with a custom binding please refer to the answer from @robmzd.
编辑:如果您遇到与自定义绑定相同的问题,请参阅@robmzd的答案。
I still haven't found a solution for consuming it as an old style Web Reference yet.
我还没有找到将它作为旧式 Web 参考使用的解决方案。
回答by Sergio
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).
我在相同的功能和相同的公司遇到了完全相同的问题,我在谷歌上花了几个小时试图找到正确的答案。经过这么多次尝试,我终于得到了它。这是我所做的:以下字符串是从 Email Vision 返回我的响应(我的主要目的是批量上传,但为了简单和测试,我换成了 getLastUpload)。
string(2180) "
字符串(2180)“
--uuid:5c8a8a1d-a29c-43d0-baaa-cb3a8c189962
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <[email protected]>
<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.
如果您查看字符串的顶部,它有一个键值和来自服务器的其他人员,这使得 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: <[email protected]>
Similarly at the bottom of the string (after the xml) the same key appears
同样在字符串的底部(在 xml 之后)出现相同的键
--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.
所以解决办法就是尽量去掉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;
}
}
回答by Derek W
If you're self-hosting a WCF service and you're consuming the service with a WCF client. You must remember to set the MessageEncodingproperty in the host like this:
如果您自托管 WCF 服务并且您使用 WCF 客户端使用该服务。您必须记住MessageEncoding在主机中设置属性,如下所示:
BasicHttpBinding binding = new BasicHttpBinding();
binding.MessageEncoding = WSMessageEncoding.Mtom;
I ran into this problem as well. My client kept throwing this Exception on start up and I couldn't figure out why until I realized that I forgot to set my bindings MessageEncodingproperty in the host application.
我也遇到了这个问题。我的客户在启动时一直抛出这个异常,直到我意识到我忘记MessageEncoding在主机应用程序中设置我的 bindings属性之前,我无法弄清楚为什么。
回答by Mark Smit
After having struggled with this for a few days, I found a remarkably simple solution for this problem:
经过几天的努力,我找到了一个非常简单的解决方案:
- Activate the Configuration Editor by selecting Tools->WCF Service Configuration Editor from the main menu in VS2010;
- Close it again;
- Right-click on the App.Config file to find a new menu item "Edit WCF Configuration";
- Click on the binding;
- Change the MessageEncoding to Mtom;
- Save.
- 在VS2010的主菜单中选择Tools->WCF Service Configuration Editor激活配置编辑器;
- 再次关闭它;
- 右键点击App.Config文件,找到一个新的菜单项“Edit WCF Configuration”;
- 点击绑定;
- 将 MessageEncoding 更改为 Mtom;
- 节省。
I hope this will help someone.
我希望这会帮助某人。
回答by SteveCav
I just got this problem because <configSections> was not the first element in <configuration>.
我刚刚遇到这个问题,因为 < configSections> 不是 < configuration> 中的第一个元素。
回答by robmzd
I had the same issue but with <customBinding>. To fix it you can configure Mtom Message Encoding using a separate <mtomMessageEncoding>configuration node under the binding.
我有同样的问题,但与<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>
回答by user3476511
I'm not sure if this is any appropriate place to put this, but I was having a hard time getting my Windows Service to connect to a WSDL (using an auto generated web reference).
我不确定这是否适合放置它,但是我很难让我的 Windows 服务连接到 WSDL(使用自动生成的 Web 参考)。
I was getting the same error as the original poster here. Since I'm not using WCF the app.config would not work for me and caused my service not to start. I did find a post on MSDNwhere AjayChigurupati states to change
我在这里遇到与原始海报相同的错误。由于我没有使用 WCF,因此 app.config 对我不起作用并导致我的服务无法启动。我确实在MSDN上找到了一篇帖子,其中 AjayChigurupati 声明要更改
public partial class WsdlService : System.Web.Services.Protocols.SoapHttpClientProtocol {...}
public partial class WsdlService : System.Web.Services.Protocols.SoapHttpClientProtocol {...}
To
到
public partial class WsdlService : Microsoft.Web.Services3.WebServicesClientProtocol {...}
public partial class WsdlService : Microsoft.Web.Services3.WebServicesClientProtocol {...}
(Make sure to add the Microsoft.Web.Services3reference to your project)
(确保将Microsoft.Web.Services3引用添加到您的项目中)
Now we have access to the boolean property RequireMtomand you can surround your calling function like so:
现在我们可以访问 boolean 属性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]));
}
Hopefully this helps someone else with the same problem in the future.
希望这可以帮助将来遇到同样问题的其他人。

