WCF: "Error creating reader for MTOM message"
Asked Answered
C

2

6

Trying to get MTOM working in a WCF client. The particular function I'm trying to consume sends an MTOM-encoded byte array of a PDF document. Using SoapUI to test the API using the WSDL works fine; however, when I try to do the same thing in the client, I get the following error:

Error creating a reader for the MTOM message
System.Xml.XmlException: MTOM messages must have type 'application/xop+xml'.
   at System.Xml.XmlMtomReader.ReadMessageContentTypeHeader(ContentTypeHeader he
ader, String& boundary, String& start, String& startInfo)
   at System.Xml.XmlMtomReader.Initialize(Stream stream, String contentType, Xml
DictionaryReaderQuotas quotas, Int32 maxBufferSize)
   at System.Xml.XmlMtomReader.SetInput(Stream stream, Encoding[] encodings, Str
ing contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDic
tionaryReaderClose onClose)
   at System.Xml.XmlMtomReader.SetInput(Byte[] buffer, Int32 offset, Int32 count
, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, In
t32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.Xml.XmlDictionaryReader.CreateMtomReader(Byte[] buffer, Int32 offse
t, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuo
tas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.Ta
keXmlReader()

Server stack trace:
   at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.Ta
keXmlReader()
   at System.ServiceModel.Channels.BufferedMessageData.DoTakeXmlReader()
   at System.ServiceModel.Channels.BufferedMessageData.GetMessageReader()
   at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData me
ssageData, RecycledMessageState recycledMessageState, Boolean[] understoodHeader
s, Boolean understoodHeadersModified)
   at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData me
ssageData, RecycledMessageState recycledMessageState)
   at System.ServiceModel.Channels.MtomMessageEncoder.ReadMessage(ArraySegment`1
 buffer, BufferManager bufferManager, String contentType)
   at System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, Buf
ferManager bufferManager, Int32 maxBufferSize, String contentType)
   at System.ServiceModel.Channels.HttpInput.ReadChunkedBufferedMessage(Stream i
nputStream)
   at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception& req
uestException)
   at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpCha
nnelRequest.WaitForReply(TimeSpan timeout)
   at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeS
pan timeout)
   at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message messag
e, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean on
eway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan tim
eout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean on
eway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCall
Message methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage req
Msg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgDa
ta, Int32 type)
   at WsApiServicePortType.getDoc(getDocRequest request)
   at WsApiServicePortTypeClient.WsApiServicePortType.getDoc(getDocReq
uest request) in C:\Users\ant\documents\visual studio 2010\Projects\Client\Cl
ient\WsApiService.cs:line 3927
   at WsApiServicePortTypeClient.getDoc(String username, String ID) in C
:\Users\ant\documents\visual studio 2010\Projects\Client\Client\WsApiServic
e.cs:line 3935
   at Client.Program.Main(String[] args) in C:\Users\ant\documents\visual stu
dio 2010\Projects\Client\Client\Program.cs:line 18

Now, I've searched all over and can't find much of relevance to this error except maybe this: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/73039d75-e078-436b-a8ab-d8c7197a976b

The recommendation in that link, though, make no sense to me. I can't see anywhere in my code where the response message exists as an object where I could modify it. So...here I am. The client that I have is extremely simple: it consists of the svcutil-generated proxy class, approx. 10 lines of code to make the call, and the app.config file. I've added certificate information to the config file and changed the messageEncoding to Mtom, but beyond that, it's all as-generated by svcutil.

Here's what the client code looks like (very simple, as you can see):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Text;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                WsApiServicePortTypeClient client = new WsApiServicePortTypeClient();
                byte[] doc = client.getRecordDoc("username0000", "1234567");
                File.WriteAllBytes(@"C:\TestRecords\wcf-test.pdf", doc);
                Console.WriteLine("Ok, check it now.");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex.Message + Environment.NewLine
                    + ex.GetBaseException().ToString() + Environment.NewLine
                    + ex.StackTrace + Environment.NewLine);
                Console.ReadLine();
            }
        }
    }
}

From the proxy class:

[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://www.<redacted>.com/ws/schemas", ClrNamespace="www.<redacted>.com.ws.schemas")]



[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://www.<redacted>.com/ws/definitions", ConfigurationName="WsApiServicePortType")]
public interface WsApiServicePortType
{
...    
    // CODEGEN: Generating message contract since the wrapper namespace (http://www.<redacted>.com/ws/schemas) of message getRecordDocRequest does not match the default value (http://www.<redacted>.com/ws/definitions)
    [System.ServiceModel.OperationContractAttribute(Action="http://localhost:8080/getRecordDoc", ReplyAction="http://www.<redacted>.com/ws/definitions/WsApiServicePortType/getRecordDocResponse")]
    [System.ServiceModel.FaultContractAttribute(typeof(www.<redacted>.com.ws.schemas.fault), Action="http://www.<redacted>.com/ws/definitions/WsApiServicePortType/getRecordDoc/Fault/wsFault", Name="fault", Namespace="http://www.<redacted>.com/ws/schemas")]
    [System.ServiceModel.XmlSerializerFormatAttribute()]
    [System.ServiceModel.ServiceKnownTypeAttribute(typeof(wsError))]
    getRecordDocResponse getRecordDoc(getRecordDocRequest request);
...    
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class WsApiServicePortTypeClient : System.ServiceModel.ClientBase<WsApiServicePortType>, WsApiServicePortType
{

    public WsApiServicePortTypeClient()
    {
    }

    public WsApiServicePortTypeClient(string endpointConfigurationName) : 
            base(endpointConfigurationName)
    {
    }

    public WsApiServicePortTypeClient(string endpointConfigurationName, string remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public WsApiServicePortTypeClient(string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(endpointConfigurationName, remoteAddress)
    {
    }

    public WsApiServicePortTypeClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) : 
            base(binding, remoteAddress)
    {
    }

...
    [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
    getRecordDocResponse WsApiServicePortType.getRecordDoc(getRecordDocRequest request)
    {
        return base.Channel.getRecordDoc(request);
    }

    public byte[] getRecordDoc(string username, string ID)
    {
        getRecordDocRequest inValue = new getRecordDocRequest();
        inValue.username = username;
        inValue.ID = ID;
        getRecordDocResponse retVal = ((WsApiServicePortType)(this)).getRecordDoc(inValue);
        return retVal.doc;
    }
...    
}

And from app.config:

<?xml version="1.0"?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <endpointBehaviors>
                <behavior name="NewBehavior0">
                    <clientCredentials>
                        <clientCertificate findValue="xxxxxxxx"
                            storeName="My" x509FindType="FindBySerialNumber" />
                    </clientCredentials>
                </behavior>
            </endpointBehaviors>
        </behaviors>
        <bindings>
            <basicHttpBinding>
                <binding name="WsApiServiceSoapBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Mtom" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
                    <security mode="Transport">
                        <transport clientCredentialType="Certificate" proxyCredentialType="None" realm=""/>
                        <message clientCredentialType="Certificate" algorithmSuite="Default"/>
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://wisp.<redacted>.com/services/WsApiService/"
                behaviorConfiguration="NewBehavior0" binding="basicHttpBinding"
                bindingConfiguration="WsApiServiceSoapBinding" contract="WsApiServicePortType"
                name="WsApiServicePort" />
        </client>
    </system.serviceModel>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

Also, though I cut it out of the config file before pasting, I've configured it for message tracing and logging, and here's what gets logged:

Outbound:

<MessageLogTraceRecord>
<HttpRequest xmlns="http://schemas.microsoft.com/2004/06/ServiceModel/Management/MessageTrace">
<Method>POST</Method>
<QueryString></QueryString>
<WebHeaders>
<VsDebuggerCausalityData>gibberish</VsDebuggerCausalityData>
</WebHeaders>
</HttpRequest>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://localhost:8080/getRecordDoc</a:Action>
<a:MessageID>urn:uuid:19966f2b-b5ed-4e30-8bd9-9180fbf527bf</a:MessageID>
<ActivityId CorrelationId="9e356eb4-cbdc-407d-991b-49ed1b831037" xmlns="http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics">95e158bd-51e7-4fe6-900b-642728f0653e</ActivityId>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">https://www.<redacted>.com/services/WsApiService/</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<getRecordDoc xmlns="http://www.<redacted>.com/ws/schemas">
<username xmlns="">username0000</username>
<ID xmlns="">1234567</ID>
</getRecordDoc>
</s:Body>
</s:Envelope>
</MessageLogTraceRecord>

And here's the response:

<MessageLogTraceRecord><![CDATA[

--MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <0.urn:uuid:[email protected]>

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><ns1:getRecordDocResponse xmlns:ns1="http://www.<redacted>.com/ws/schemas"><doc><xop:Include href="cid:1.urn:uuid:[email protected]" xmlns:xop="http://www.w3.org/2004/08/xop/include"/></doc></ns1:getRecordDocResponse></soapenv:Body></soapenv:Envelope>
--MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
Content-ID: <1.urn:uuid:[email protected]>

%PDF-1.5
(blah blah blah Wingdings!)

--MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx--
]]></MessageLogTraceRecord>

The trace log shows that the "Construct ChannelFactory" and "Open ClientBase" steps complete successfully, but when it tries "Process action http://localhost:8080/getRecordDoc, it fails after starting the activity boundary as follows:

<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2013-06-17T19:10:31.2623643Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}" />
<Execution ProcessName="Client.vshost" ProcessID="12040" ThreadID="10" />
<Channel />
<Computer>computer</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>Client.vshost.exe</AppDomain>
<Exception>
<ExceptionType>System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=publickeytokeninfo</ExceptionType>
<Message>Error creating a reader for the MTOM message</Message>
<StackTrace>
at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.TakeXmlReader()
at System.ServiceModel.Channels.BufferedMessageData.DoTakeXmlReader()
at System.ServiceModel.Channels.BufferedMessageData.GetMessageReader()
at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState, Boolean[] understoodHeaders, Boolean understoodHeadersModified)
at System.ServiceModel.Channels.BufferedMessage..ctor(IBufferedMessageData messageData, RecycledMessageState recycledMessageState)
at System.ServiceModel.Channels.MtomMessageEncoder.ReadMessage(ArraySegment`1 buffer, BufferManager bufferManager, String contentType)
at System.ServiceModel.Channels.MessageEncoder.ReadMessage(Stream stream, BufferManager bufferManager, Int32 maxBufferSize, String contentType)
at System.ServiceModel.Channels.HttpInput.ReadChunkedBufferedMessage(Stream inputStream)
at System.ServiceModel.Channels.HttpInput.ParseIncomingMessage(Exception&amp; requestException)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)
at WsApiServicePortType.getRecordDoc(getRecordDocRequest request)
at WsApiServicePortTypeClient.WsApiServicePortType.getRecordDoc(getRecordDocRequest request)
at WsApiServicePortTypeClient.getRecordDoc(String username, String stiId)
at Client.Program.Main(String[] args)
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
</StackTrace>
<ExceptionString>System.ServiceModel.CommunicationException: Error creating a reader for the MTOM message ---&gt; System.Xml.XmlException: MTOM messages must have type 'application/xop+xml'.
   at System.Xml.XmlMtomReader.ReadMessageContentTypeHeader(ContentTypeHeader header, String&amp; boundary, String&amp; start, String&amp; startInfo)
   at System.Xml.XmlMtomReader.Initialize(Stream stream, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize)
   at System.Xml.XmlMtomReader.SetInput(Stream stream, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.Xml.XmlMtomReader.SetInput(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.Xml.XmlDictionaryReader.CreateMtomReader(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.TakeXmlReader()
   --- End of inner exception stack trace ---</ExceptionString>
<InnerException>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=publickeytokeninfo</ExceptionType>
<Message>MTOM messages must have type 'application/xop+xml'.</Message>
<StackTrace>
at System.Xml.XmlMtomReader.ReadMessageContentTypeHeader(ContentTypeHeader header, String&amp; boundary, String&amp; start, String&amp; startInfo)
at System.Xml.XmlMtomReader.Initialize(Stream stream, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize)
at System.Xml.XmlMtomReader.SetInput(Stream stream, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
at System.Xml.XmlMtomReader.SetInput(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
at System.Xml.XmlDictionaryReader.CreateMtomReader(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.TakeXmlReader()
</StackTrace>
<ExceptionString>System.Xml.XmlException: MTOM messages must have type 'application/xop+xml'.
   at System.Xml.XmlMtomReader.ReadMessageContentTypeHeader(ContentTypeHeader header, String&amp; boundary, String&amp; start, String&amp; startInfo)
   at System.Xml.XmlMtomReader.Initialize(Stream stream, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize)
   at System.Xml.XmlMtomReader.SetInput(Stream stream, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.Xml.XmlMtomReader.SetInput(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.Xml.XmlDictionaryReader.CreateMtomReader(Byte[] buffer, Int32 offset, Int32 count, Encoding[] encodings, String contentType, XmlDictionaryReaderQuotas quotas, Int32 maxBufferSize, OnXmlDictionaryReaderClose onClose)
   at System.ServiceModel.Channels.MtomMessageEncoder.MtomBufferedMessageData.TakeXmlReader()</ExceptionString>
</InnerException>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

I'm thinking that this has something to do with the contract wrapper as indicated by the CODEGEN messages in the proxy class file. I can't find anything about that message, though, that would confirm that.

Any help is greatly appreciated.

Coltin answered 18/6, 2013 at 17:29 Comment(9)
please publish the response log - including http headers. best if you take them from fiddler.Adamson
Response log added. Dunno why I didn't find this in the message log earlier. It seems to me to be well-formed, but the WCF message logging system flagged it as malformed.Coltin
please also publish the response http headers. you have published just the body (since the body is multipart it has some internal http headers but I need to see the real ones). they should be in the wcf log, otherwise use fiddler.Adamson
I must be an idiot because I can't get Fiddler configured properly to listen in on the channel without the endpoint crying foul. Best I can do is the headers from SoapUI: X-Backside-Transport OK OK Transfer-Encoding chunked Date Thu, 20 Jun 2013 19:07:07 GMT #status# HTTP/1.1 200 OK X-Client-IP xx.xxx.xxx.xx Connection Keep-Alive Content-Type multipart/related; boundary="MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; start-info="text/xml"; type="text/xml"; start="<0.urn:uuid:[email protected]>" Server Apache-Coyote/1.1Coltin
the Content-Type header here is "multipart/related". This is not the right header to send for MTOM response, so I believe this is as server error. As the exception mentions, "MTOM messages must have (content) type 'application/xop+xml'". Try to hard code it on the server, or temporaly change it in some proxy to see that wcf will work (you could also try a wcf custom message encoder, should override one property - ContentType - to return right type). Note there are binary payload (file attachment) standards that allow content type of "multipart/related" but wcf does not support them. However -Adamson
here the message payload uses the <xop> tag so I beleive the server does mean to send mtom but does not use the right content-type header.Adamson
BTW here is an implementaion for the otehr attachment standard I mentioned for wcf. it may work for you, the pdf will be available in some property. but on the otehr hand since the xml uses <xop> it might not be valid so you might need to tweak it in an encoder anyway. so the best is to solve the root problem in the server. wcfswaencoder.codeplex.comAdamson
Unfortunately, the service is run by a third party that has a poor history of responding to such requests. I'll have to work on a custom encoder, it seems. Thanks for the help. Should post that as an answer so I can give you credit.Coltin
I just ran into the same thing. For me the problem is that the server is returning a non-MTOM content type: Content-Type: application/soap+xml; charset=utf-8; action="http://...".Hum
A
1

UPDATE: As @Tone mentions in the comments, the original accepted answer below is wrong. It is actually valid (and required) for the outer Content-Type of an MTOM HTTP response header to have the value "multipart/related". This is the header the original poster received:

Content-Type    multipart/related; boundary="MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; start-info="text/xml"; type="text/xml"; start="<0.urn:uuid:[email protected]>" 

The real problem seems that the "type" attribute is "text/xml" and not "application/xop+xml".

==============================================

Original answer:

The Content-Type header here is "multipart/related". This is not the right header to send for MTOM response, so I believe this is as server error. As the exception mentions, "MTOM messages must have (content) type 'application/xop+xml'". Try to hard code it on the server, or temporaly change it in some proxy to see that wcf will work (you could also try a wcf custom message encoder, should override one property - ContentType - to return right type). Note there are binary payload (file attachment) standards that allow content type of "multipart/related" but wcf does not support them. However here the message payload uses the tag so I beleive the server does mean to send mtom but does not use the right content-type header.

BTW here is an implementaion for the other attachment standard I mentioned for wcf. it may work for you, the pdf will be available in some property. but on the other hand since the xml uses it might not be valid so you might need to tweak it in an encoder anyway. so the best is to solve the root problem in the server.

Adamson answered 20/6, 2013 at 21:30 Comment(4)
According to the W3c spec on MTOM, Section 3.2, 1st bullet the content type of the outer-package MUST be "multipart/related" w3.org/TR/soap12-mtom. I believe this answer is wrong - how did you come to this conclusion?Trapezius
I'm looking at section 3.2 "Serialization of a SOAP message" and it specifies application/xop+xml and not multipart/relatedAdamson
It specifies 2 things: 1) content-type must be multipart/related. and 2) type must be "application/xop+xml". My understanding is that the type parameter is a "sub-member" of content-type. So on the wire it would look like this: Content-Type: multipart/related; type="application/xop+xml"; boundary="urn:uuid:cfd954f5-e132-4dc1-90b1-1355bbbbfab5"; start="<[email protected]>"; start-info="application/soap+xml;charset=utf-8";charset=utf-8Trapezius
I also found this SO post that supports my position - what am I missing here? #11091607.Trapezius
P
5

For my case, I was getting the indicated error, in my binding I had

maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"

it did not start working until I added:

maxBufferSize="2147483647"

Just incase anyone has the same issue.

Philipps answered 2/8, 2017 at 17:57 Comment(3)
Did you have any other settings in your mtomMessageEncoding tag? I currently have <mtomMessageEncoding maxBufferSize="2147483647" messageVersion="Soap12">Breastsummer
@Breastsummer I was not using a mtomMessageEncoding tag, I just had messageEncoding="Mtom" set in my binding element.Philipps
Oh okay. I'm using custom binding. Thanks for clarifying.Breastsummer
A
1

UPDATE: As @Tone mentions in the comments, the original accepted answer below is wrong. It is actually valid (and required) for the outer Content-Type of an MTOM HTTP response header to have the value "multipart/related". This is the header the original poster received:

Content-Type    multipart/related; boundary="MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; start-info="text/xml"; type="text/xml"; start="<0.urn:uuid:[email protected]>" 

The real problem seems that the "type" attribute is "text/xml" and not "application/xop+xml".

==============================================

Original answer:

The Content-Type header here is "multipart/related". This is not the right header to send for MTOM response, so I believe this is as server error. As the exception mentions, "MTOM messages must have (content) type 'application/xop+xml'". Try to hard code it on the server, or temporaly change it in some proxy to see that wcf will work (you could also try a wcf custom message encoder, should override one property - ContentType - to return right type). Note there are binary payload (file attachment) standards that allow content type of "multipart/related" but wcf does not support them. However here the message payload uses the tag so I beleive the server does mean to send mtom but does not use the right content-type header.

BTW here is an implementaion for the other attachment standard I mentioned for wcf. it may work for you, the pdf will be available in some property. but on the other hand since the xml uses it might not be valid so you might need to tweak it in an encoder anyway. so the best is to solve the root problem in the server.

Adamson answered 20/6, 2013 at 21:30 Comment(4)
According to the W3c spec on MTOM, Section 3.2, 1st bullet the content type of the outer-package MUST be "multipart/related" w3.org/TR/soap12-mtom. I believe this answer is wrong - how did you come to this conclusion?Trapezius
I'm looking at section 3.2 "Serialization of a SOAP message" and it specifies application/xop+xml and not multipart/relatedAdamson
It specifies 2 things: 1) content-type must be multipart/related. and 2) type must be "application/xop+xml". My understanding is that the type parameter is a "sub-member" of content-type. So on the wire it would look like this: Content-Type: multipart/related; type="application/xop+xml"; boundary="urn:uuid:cfd954f5-e132-4dc1-90b1-1355bbbbfab5"; start="<[email protected]>"; start-info="application/soap+xml;charset=utf-8";charset=utf-8Trapezius
I also found this SO post that supports my position - what am I missing here? #11091607.Trapezius

© 2022 - 2024 — McMap. All rights reserved.