Я уверен на 90%, что работаю над тем же проектом, что и вы, ребята.Этот запрос на мыло немного знаком: -)
Мы прошли большую часть пути, переключившись на WCF и фактически написав вручную код объекта запроса (создав классы, соответствующие формату мыла, а затем используяАтрибуты xmlelement, чтобы украсить его так, чтобы он выглядел как их запрос мыла. Сам файл объявлен как Byte () в классе Attachment, а также декорирован xmlelement).
Вот что контракт WCF и частьмодель данных выглядит так.Реальная модель данных имеет кучу дополнительных классов (область приложения, область данных, задание и т. Д.), Но этого достаточно для понимания того, как она структурирована.Важной частью является File as Byte ().Вот он на Vb.net ...
Public Class WarrantyClaim
<XmlElement(Order:=0)> Public OEMClaimNumber As String = ""
<XmlElement(Order:=1, namespace:="http://www.gm.com/2006/GWM")> Public Attachment As New Attachment
End Class
Public Class Attachment
<XmlElement(Order:=0)> Public File As Byte()
<XmlElement(Order:=1)> Public Filename As String
End Class
<ServiceContract(XmlSerializerFormat()> _
Public Interface IService
<OperationContract(action:="http://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment")> _
Sub ProcessMessage(ByVal payload As WarrantyClaim)
End Interface
Далее у вас есть ваш клиент WCF, он почти такой же, как и все клиенты WCF.
Public Class GmgwClient
Inherits System.ServiceModel.ClientBase(Of IService)
Implements IService
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal configName As String)
MyBase.New(configName)
End Sub
Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding, ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(binding, remoteAddress)
End Sub
Public Sub ProcessMessage(ByVal payload As Payload) Implements IService.ProcessMessage
MyBase.Channel.ProcessMessage(payload)
End Sub
End Class
Наконец, выполучил app.config.Вот волшебство, потому что мы говорим WCF использовать Mtom для отправки сообщения.Это возьмет Byte () и разделит его на отдельный раздел MIME, заменив его XOP: Include.Обратите внимание, что сейчас я просто отправляю его через localhost, чтобы увидеть запрос с помощью tcpTrace.Вы можете погуглить это приложение, но оно в основном захватит запрос, чтобы мы могли посмотреть, как оно выглядит.Я настроил tcpTrace для прослушивания порта 84.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WsHttpMtomBinding" messageEncoding="Mtom">
<security mode="None">
<transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
</security>
<reliableSession enabled="false" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:84/ProcessMessage" binding="wsHttpBinding" bindingConfiguration="WsHttpMtomBinding" contract="MyAppNameSpace.IService" name="preprod"/>
</client>
</system.serviceModel>
Наконец, вот фактический вызов клиента WCF для выполнения запроса.
Dim x As New WarrantyClaim
x.OEmClaimNumber = "12345"
x.Attachment = New Attachment
x.Attachment.Filename = "sample.gif"
x.Attachment.File = IO.File.ReadAllBytes("C:\sample.gif")
Dim y As New GmgwClient("preprod")
y.ProcessMessage(x)
А вот трассировка, которую мы получили через tcpTrace,У него правильная базовая структура, и ему удалось вытащить двоичные данные из XML и поместить их в отдельный раздел MIME.
POST /ProcessMessage HTTP/1.1
MIME-Version: 1.0
Content-Type: multipart/related; type="application/xop+xml";start="<http://tempuri.org/0>";boundary="uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1";start-info="application/soap+xml"
VsDebuggerCausalityData: uIDPoysDMCv023ZIjK0Cpp504ooAAAAA//jfaCaohkab2Zx/EU7gpLZDcUldWtlGr1j4ZnrfKl4ACQAA
Host: localhost:84
Content-Length: 55125
Expect: 100-continue
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
--uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1
Content-ID: <http://tempuri.org/0>
Content-Transfer-Encoding: 8bit
Content-Type: application/xop+xml;charset=utf-8;type="application/soap+xml"
<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://www.starstandards.org/webservices/2005/10/transport/operations/ProcessMessage/v1_01/ProcessAttachment</a:Action>
<a:MessageID>urn:uuid:a85374e6-c8ca-4328-ad32-6e8b88a5ca59</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://localhost:84/ProcessMessage</a:To>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ProcessMessage xmlns="http://www.starstandards.org/webservices/2005/10/transport">
<payload xsi:type="gwm:WarrantyClaimExtended">
<OEMClaimNumber>12345</OEMClaimNumber>
<Attachment xmlns="http://www.gm.com/2006/GWM">
<File>
<xop:Include href="cid:http%3A%2F%2Ftempuri.org%2F1%2F634618782531246992" xmlns:xop="http://www.w3.org/2004/08/xop/include"/>
</File>
<Filename>sample.gif</Filename>
</Attachment>
</payload>
</ProcessMessage>
</s:Body>
</s:Envelope>
--uuid:501aa27d-9dd1-4f8a-b56d-3fbf327e7be6+id=1
Content-ID: <http://tempuri.org/1/634618782531246992>
Content-Transfer-Encoding: binary
Content-Type: application/octet-stream
GIF89a<BinaryStuff>
Как я уже упоминал ранее - у нас все еще есть некоторые проблемы.В заголовке мыла отсутствуют некоторые теги ... но я думаю, мы сможем это выяснить.Настоящая проблема в том, что Content-ID НЕ в формате, который может принять наш партнер - они ожидают что-то вроде <1.a33c2d7e84634122705ebc71e53d95d4c2683d726ba54e14@apache.org> и .net форматирует их как http://tempuri.org/1/634618782531246992. Это вызывает их вебСбой обработчика службы, поскольку он не знает, как прочитать экранированные идентификаторы содержимого внутри сообщения мыла.