Client found response content type of ‘multipart/related’, but expected ‘text/xml’.
2012-02-15 16:32
555 查看
Refereced from:
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.
instead of
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.
Having made my SoapExtension, which I gave the name ModifierExtension, all I needed to do was add the custom soapExtensionType to the system.web/webServices/soapExtensionTypes section of the App.config file.
Now the desktop client works as expected, getting a correct response on each call.
Complete source code for ModifierExtension.
Complete system.web section of App.config file
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ------=_Part_0_9729661.1239018752715 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-- |
1 2 3 4 5 6 7 8 9 | <?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> |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /* RegEx to select the soap Envelope */ 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(); } |
1 | <add group="Low" priority="1" type="Minc.SoapExtensions.ModifierExtension, Minc.SoapExtensions" /> |
Complete source code for ModifierExtension.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | using System; 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; } } } } |
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="utf-8"?> <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; type="application/xop+xml"; start="<soap.x
- client found response content type of text/html charset=utf-8 but expected text/xml
- CXF报错后,独立解决->unwinding now Response was of unexpected text/html ContentType.
- The content type application/json of the response message does not match the content type of the binding (application/soap+xml;
- web.xml The content of element type "web-app" must match "
- response.setContentType("text/html"); 必须注明,否则导致解析不正确了
- (7)获取表单参数3种方法、response.setContentType("text/html;charset=utf-8")
- contentType 'text/xml; charset=UTF-8' conflicts问题
- tld xml cvc-complex-type.2.4.a: Invalid content was found starting with element
- Caused by: org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting
- WebService开发时错误,Received content of invalid Content-Type setting:text/html - SOAP expects "text/xml"
- illegal to have multiple occurrences of contentType with different values (old: text/html; charset=
- No qualifying bean of type [org.apache.solr.client.solrj.SolrServer] found for dependency: expected
- 解决XML中报“cvc-complex-type.2.4.a: Invalid content was found starting with element ”错误
- 配置web.xml 的时候 web-app 标签报错The content of element type "web-app" must match "
- "org.xml.sax.SAXParseException: The content of element type "class" must match" 异常解决
- Web.xml配置<taglib>标签报错问题(cvc-complex-type.2.4.a: Invalid content was found starting with element 'tag
- struts-config.xml配置文件顺序异常: The content of element type "struts-config" must match
- SpringMVC+idea中web.xml文件的The content of element type "web-app" must match问题