Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
来源:互联网 发布:mac电脑excel怎么换行 编辑:程序博客网 时间:2024/05/16 20:29
Reference: http://coding.baneworld.nl/2009/02/client-found-response-content-type-of-multipartrelated-but-expected-textxml/
While creating a desktop client for a third party SOAP Web service I ran into the following error.
Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
After trying a few different methods to generate the SOAP interfaces and classes I still was gettings errors.
Spending some time “googling” for a solution I found some references MTOM, Java/.NET interop issues, HTTP Status: 100 Continue, MIME and several other possible cauzes.
Just to make sure the webservice was working correctly I used soapUI to check all operations. Everything was working fine.
Testing all SOAP operations from .NET i found out that all invalid calls returned a correct SOAP response containing the error.
All valid calls generated the Client found response content type of ‘multipart/related’, but expected ‘text/xml’ error.
Using a custom SoapExtension i dumped all requests and response to log files. All valid ops requests got a response containing the expected ops result with one big issue. The response was in MIME and not the SOAP XML .NET expected.
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:Header><api-version>1.5.8</api-version></soap:Header>
<soap:Body>
<ns2:getDatabaseFieldsResponse xmlns:ns2="http://api.xxxxxxxx.xxx/">
<databaseField><label>Email-adres</label><name>email</name><defaultValue></defaultValue><type>email</type><key>true</key><mandatory>true</mandatory><minimumLength>0</minimumLength><maximumLength>0</maximumLength></databaseField>
</ns2:getDatabaseFieldsResponse>
</soap:Body>
</soap:Envelope>
------=_Part_0_9729661.1239018752715--
instead of
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header><api-version>1.5.8</api-version></soap:Header>
<soap:Body>
<ns2:getDatabaseFieldsResponse xmlns:ns2="http://api.xxxxxxxx.xxx/">
<databaseField><label>Email-adres</label><name>email</name><defaultValue></defaultValue><type>email</type><key>true</key><mandatory>true</mandatory><minimumLength>0</minimumLength><maximumLength>0</maximumLength></databaseField>
</ns2:getDatabaseFieldsResponse>
</soap:Body>
</soap:Envelope>
After spending some extra time searching the Web for anwsers, which I didn’t find, i figured i could do a simple ‘Quick & Dirty’ solution using a SoapExtension to fix the response.
By using a custom SoapExtension I could intercept the response and modify the content so .NET would except it. Info on creating and using a SoapExtension to intercept SOAP calls can be found here (MSDN).
First thing I needed to do was write a small regular expression to extract the SOAP Envelope from the response stream.
The regex I use is “<soap:Envelope(.*?/n*?)*?</soap:Envelope>“.
Using this regex on the response content matches the SOAP Envelope, which I then use to make a correct response stream. By making a new Stream which I fill with a xml declaration and the SOAP Envelope, replacing the original Stream with this new Stream.
Regex m_Regex = new Regex("<soap:Envelope(.*?/n*?)*?</soap:Envelope>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
/* fix stream */
protected internal void FixStream(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
string content = reader.ReadToEnd();
string newcontent = "";
Match regMatch;
for (regMatch = m_Regex.Match(content); regMatch.Success; regMatch = regMatch.NextMatch())
{
// Process the words
int nStart = regMatch.Index;
int nLenght = regMatch.Length;
newcontent += content.Substring(nStart, nLenght);
}
writer.WriteLine("<?xml version="1.0" encoding="utf-8"?>;" + newcontent);
writer.Flush();
}
Now the desktop client works as expected, getting a correct response on each call.
Complete source code for ModifierExtension.
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Text.RegularExpressions;
namespace Minc.SoapExtensions
{
public class ModifierExtension : SoapExtension
{
private Stream m_OldStream;
private Stream m_NewStream;
private Regex m_Regex;
// Save the Stream representing the SOAP request or SOAP response into a local memory buffer.
public override Stream ChainStream(Stream stream)
{
m_OldStream = stream;
m_NewStream = new MemoryStream();
return m_NewStream;
}
public ModifierExtension()
{
/* RegEx to select the soap Envelope */
m_Regex = new Regex("<soap:Envelope(.*?/n*?)*?</soap:Envelope>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
}
public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute)
{
return "";
}
// The SOAP extension was configured to run using a configuration file
// instead of an attribute applied to a specific Web service
// method.
public override object GetInitializer(Type webServiceType)
{
return "";
}
// Receive the file name stored by GetInitializer and store it in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
}
// If the SoapMessageStage is such that the SoapRequest or
// SoapResponse is still in the SOAP format to be sent or received,
// save it out to a file.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
WriteOutput(message);
break;
case SoapMessageStage.BeforeDeserialize:
WriteInput(message);
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}
/* process incoming message*/
private void WriteInput(SoapMessage message)
{
/* set ContentType to 'text/xml' to match the modified content*/
message.ContentType = "text/xml";
FixStream(m_OldStream, m_NewStream);
m_NewStream.Position = 0;
}
/* process outgoing message*/
public void WriteOutput(SoapMessage message)
{
m_NewStream.Position = 0;
Copy(m_NewStream, m_OldStream);
}
/* copy stream */
protected internal void Copy(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
/* fix stream */
protected internal void FixStream(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
string content = reader.ReadToEnd();
string newcontent = "";
Match regMatch;
for (regMatch = m_Regex.Match(content); regMatch.Success; regMatch = regMatch.NextMatch())
{
// Process the matches. Should only be one Match, so newcontent += regMatch.ToSting(); would be enough.
int nStart = regMatch.Index;
int nLenght = regMatch.Length;
newcontent += content.Substring(nStart, nLenght);
}
//Add xml start tag and soap envelope to output stream
writer.WriteLine("<?xml version="1.0" encoding="utf-8"?>" + newcontent);
writer.Flush();
}
}
// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to a Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class ModifierExtensionAttribute : SoapExtensionAttribute
{
private int m_Priority;
public override Type ExtensionType
{
get { return typeof(ModifierExtension); }
}
public override int Priority
{
get { return m_Priority; }
set { m_Priority = value; }
}
}
}
<configuration>
...
<system.web>
<webServices>
<soapExtensionTypes>
<add group="Low" priority="1" type="Minc.SoapExtensions.ModifierExtension, Minc.SoapExtensions" />
</soapExtensionTypes>
</webServices>
</system.web>
...
</configuration>
- Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
- Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
- client found response content type of text/html charset=utf-8 but expected text/xml
- Client found response content type of 'multipart/related; type="application/xop+xml"; start="<soap.x
- Solr4.6 Expected content type application/octet-stream but got text/html 解决办法
- No unique bean of type is defined: expected single bean but found 0
- No qualifying bean of type is defined: expected single matching bean but found 2
- solrj使用报错:HttpSolrServer$RemoteSolrException: Expected mime type application/xml but got text/html
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- Expected mime type application/octet-stream but got text/html.
- Spring的JUnit错误:NoSuchBeanDefinitionException: No unique bean of type,expected single matching bean but found 2 [dataSource1,data
- Sybase ASE 12.5.2 Develope Edition
- jvm调优总结
- Magento 网站备份
- 何为Hibernate
- 系统属性
- Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
- Hibernate使用
- Java代码编写的30条建议
- VC 进程与进程通信
- J2EE技术
- 程序员必须知道的英语
- 开发人员一定要加入收藏夹的网站
- Java日期转换SimpleDateFormat格式大全 和 判断是否为合法的日期时间字符串?
- 名词解释:SOA