WCF: ошибка при создании средства чтения для сообщения MTOM

Попытка заставить MTOM работать в клиенте WCF. Конкретная функция, которую я пытаюсь использовать, отправляет массив байтов в формате MTOM документа PDF. Использование SoapUI для тестирования API с помощью WSDL работает нормально; однако, когда я пытаюсь сделать то же самое в клиенте, я получаю следующую ошибку:

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

Теперь я искал повсюду и не могу найти ничего, что имело бы отношение к этой ошибке, кроме возможно этого: http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/73039d75-e078-436b-a8ab-d8c7197a976b

Рекомендация в этой ссылке, однако, не имеет смысла для меня. Я не вижу нигде в своем коде, где ответное сообщение существует как объект, где я мог бы его изменить. И вот я здесь. Клиент, который у меня есть, предельно прост: он состоит из прокси-класса, сгенерированного svcutil, прим. 10 строк кода для вызова и файл app.config. Я добавил информацию о сертификате в файл конфигурации и изменил messageEncoding на Mtom, но помимо этого все это сгенерировано svcutil.

Вот как выглядит клиентский код (как видите, очень просто):

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

Из прокси-класса:

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

И из 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>

Кроме того, хотя я вырезал его из файла конфигурации перед вставкой, я настроил его для отслеживания и регистрации сообщений, и вот что регистрируется:

Исходящий:

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

И вот ответ:

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

Журнал трассировки показывает, что шаги «Создать ChannelFactory» и «Открыть ClientBase» выполнены успешно, но когда он пытается «Обработать действие http://localhost:8080/getRecordDoc», происходит сбой после запуска границы действия следующим образом:

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

Я думаю, что это как-то связано с оболочкой контракта, на что указывают сообщения CODEGEN в файле прокси-класса. Однако я не могу найти ничего об этом сообщении, что подтверждало бы это.

Любая помощь приветствуется.


person Ant    schedule 18.06.2013    source источник
comment
пожалуйста, опубликуйте журнал ответов, включая заголовки http. лучше всего, если вы возьмете их у скрипача.   -  person Yaron Naveh    schedule 18.06.2013
comment
Добавлен журнал ответов. Не знаю, почему я не нашел это в журнале сообщений раньше. Мне кажется, что он правильно сформирован, но система регистрации сообщений WCF пометила его как искаженный.   -  person Ant    schedule 19.06.2013
comment
Пожалуйста, также опубликуйте заголовки ответа http. вы опубликовали только тело (поскольку тело состоит из нескольких частей, у него есть некоторые внутренние заголовки http, но мне нужно увидеть настоящие). они должны быть в журнале wcf, в противном случае используйте скрипач.   -  person Yaron Naveh    schedule 19.06.2013
comment
Я должен быть идиотом, потому что я не могу правильно настроить Fiddler для прослушивания канала без того, чтобы конечная точка не ругалась. Лучшее, что я могу сделать, это заголовки из 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; граница = MIMEBoundaryurn_uuid_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; старт-информация = текст/xml; тип=текст/xml; start=‹0.urn:uuid:[email protected]› Сервер Apache-Coyote/1.1   -  person Ant    schedule 20.06.2013
comment
заголовок Content-Type здесь многочастный/связанный. Это неправильный заголовок для отправки ответа MTOM, поэтому я считаю, что это ошибка сервера. Как упоминается в исключении, сообщения MTOM должны иметь тип (содержимого) «application/xop+xml». Попробуйте жестко закодировать его на сервере или временно изменить его в каком-либо прокси-сервере, чтобы убедиться, что wcf будет работать (вы также можете попробовать собственный кодировщик сообщений wcf, который должен переопределить одно свойство — ContentType — для возврата правильного типа). Обратите внимание, что существуют стандарты двоичной полезной нагрузки (вложения файла), которые допускают тип содержимого multipart/related, но wcf их не поддерживает. Тем не мение -   -  person Yaron Naveh    schedule 20.06.2013
comment
здесь полезная нагрузка сообщения использует тег ‹xop›, поэтому я полагаю, что сервер действительно намеревается отправить mtom, но не использует правильный заголовок типа содержимого.   -  person Yaron Naveh    schedule 20.06.2013
comment
Кстати, вот реализация другого стандарта вложения, который я упомянул для wcf. это может сработать для вас, pdf будет доступен в каком-то свойстве. но, с другой стороны, поскольку xml использует ‹xop›, он может быть недействительным, поэтому вам все равно может потребоваться настроить его в кодировщике. поэтому лучше всего решить корневую проблему на сервере. wcfswaencoder.codeplex.com   -  person Yaron Naveh    schedule 20.06.2013
comment
К сожалению, служба управляется третьей стороной, которая плохо отвечает на такие запросы. Придется поработать над кастомным энкодером, похоже. Спасибо за помощь. Должен опубликовать это как ответ, чтобы я мог отдать вам должное.   -  person Ant    schedule 20.06.2013
comment
Я просто столкнулся с тем же самым. Для меня проблема в том, что сервер возвращает тип контента, отличный от MTOM: Content-Type: application/soap+xml; кодировка=utf-8; действие=http://....   -  person Rick Strahl    schedule 22.10.2014


Ответы (2)


ОБНОВЛЕНИЕ: Как упоминает @Tone в комментариях, исходный принятый ответ ниже неверен. На самом деле допустимо (и необходимо), чтобы внешний Content-Type заголовка HTTP-ответа MTOM имел значение «multipart/related». Это заголовок, который получил исходный постер:

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

Настоящая проблема заключается в том, что атрибут "type" - это "text/xml", а не "application/xop+xml".

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

Оригинальный ответ:

Заголовок Content-Type здесь "multipart/related". Это неправильный заголовок для отправки ответа MTOM, поэтому я считаю, что это ошибка сервера. Как упоминается в исключении, «сообщения MTOM должны иметь тип (содержимого)« application/xop + xml »». Попробуйте жестко закодировать его на сервере или временно изменить его в каком-либо прокси-сервере, чтобы убедиться, что wcf будет работать (вы также можете попробовать собственный кодировщик сообщений wcf, который должен переопределить одно свойство — ContentType — для возврата правильного типа). Обратите внимание, что существуют стандарты двоичной полезной нагрузки (вложения файла), которые допускают тип содержимого «многочастный/связанный», но wcf их не поддерживает. Однако здесь полезная нагрузка сообщения использует тег, поэтому я полагаю, что сервер действительно намеревается отправить mtom, но не использует правильный заголовок типа контента.

Кстати, вот реализация другого стандарта прикрепления, который я упомянул для wcf. это может сработать для вас, pdf будет доступен в каком-то свойстве. но, с другой стороны, поскольку xml использует его, он может быть недействительным, поэтому вам все равно может потребоваться настроить его в кодировщике. поэтому лучше всего решить корневую проблему на сервере.

person Yaron Naveh    schedule 20.06.2013
comment
Согласно спецификации W3c по MTOM, раздел 3.2, 1-й пункт, тип содержимого внешнего пакета ДОЛЖЕН быть multipart/related w3.org/TR/soap12-mtom. Я считаю, что этот ответ неверен - как вы пришли к такому выводу? - person Tone; 10.12.2014
comment
Я просматриваю раздел 3.2 Сериализация сообщения SOAP, и в нем указано application/xop+xml, а не составное/связанное - person Yaron Naveh; 23.12.2014
comment
Он указывает 2 вещи: 1) тип контента должен быть составным/связанным. и 2) тип должен быть application/xop+xml. Насколько я понимаю, параметр типа является подэлементом типа контента. Таким образом, в сети это будет выглядеть так: Content-Type: multipart/related; тип=приложение/xop+xml; граница=урна:uuid:cfd954f5-e132-4dc1-90b1-1355bbbbfab5; start=‹[email protected]›; старт-информация = приложение/мыло + XML; набор символов = utf-8; набор символов = utf-8 - person Tone; 29.12.2014
comment
Я также нашел этот пост SO, который поддерживает мою позицию - что мне здесь не хватает? stackoverflow.com/ вопросы/11091107/. - person Tone; 29.12.2014

В моем случае я получал указанную ошибку, в моей привязке у меня было

maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"

он не начал работать, пока я не добавил:

maxBufferSize="2147483647"

На всякий случай у кого такая же проблема.

person Popo    schedule 02.08.2017
comment
Были ли у вас какие-либо другие настройки в вашем теге mtomMessageEncoding? В настоящее время у меня есть ‹mtomMessageEncoding maxBufferSize=2147483647 messageVersion=Soap12› - person MindGame; 29.03.2018
comment
@MindGame Я не использовал тег mtomMessageEncoding, я просто установил messageEncoding = Mtom в элементе привязки. - person Popo; 29.03.2018
comment
Ох, ладно. Я использую пользовательскую привязку. Спасибо за разъяснения. - person MindGame; 29.03.2018