как принять запрос Http MIME через HTTP через службу WCF в BizTalk

У меня есть требование принимать HTTP-запрос MIME через HTTP в BizTalk.

Я создал службу, опубликовав свою схему с помощью мастера публикации WCF, и он отлично работает для стандарта SOAP + WSDL Envelope Standard, но как мне реализовать то же самое для сообщения HTTP / MIME Multipart?

Я попытался предоставить компонент декодера MIME на этапе декодирования конвейера, но он выдает ошибку:

_415 Cannot process the message because the content type 'multipart/form-data; boundary=06047b04fd8d6d6866ed55ba' was not the expected type 'application/soap+xml; charset=utf-8'._

Вот мой образец сообщения MIME, которое я использовал:

POST /core/Person HTTP/1.1 
Host: server_host:server_port
Content-Length: 244508 
Content-Type: multipart/form-data; boundary=XbCY 
--XbCY
Content-Disposition: form-data; name=“Name“
QWERTY 
--XbCY Content-Disposition: form-data; name=“Phno No" 
12234 
--XbCY 
Content-Disposition: form-data; name=“Address" 
00a0d91e6fa6 

Могу ли я использовать ту же службу с той же конечной точкой? Если да, то какие все изменения я должен внести в свой сервис?

Должен ли я использовать какой-либо настраиваемый компонент конвейера?


person Chopperla    schedule 03.01.2013    source источник


Ответы (1)


Вы захотите иметь порт приема типа HTTP и использовать BTSHTTPReceive.dll, поскольку похоже, что конверта SOAP нет. Таким образом, вам в основном нужна новая конечная точка, а не пытаться заставить работать WCF.

Да, вам придется использовать пользовательский компонент конвейера.

Также, когда вы получаете сообщение MIME, которое является multipart / form-data, вам необходимо прочитать Как обработать сообщение multipart / form-data, отправленное в BTSHttpReceive.dll, которое добавляет« MIME- Версия: 1.0 ”в сообщение, чтобы можно было использовать стандартный компонент конвейера декодера MIME.

public IBaseMessage Execute(IPipelineContext pc, IBaseMessage inmsg)
    {
        IBaseMessagePart bodyPart = inmsg.BodyPart;
        if (bodyPart!=null)
        {
            byte[] prependByteData  = ConvertToBytes(prependData);
            byte[] appendByteData   = ConvertToBytes(appendData);

            string headersString = inmsg.Context.Read("InboundHttpHeaders", "http://schemas.microsoft.com/BizTalk/2003/http-properties").ToString();
            string[] headers = headersString.Split(new Char[] {'\r','\n' }, StringSplitOptions.RemoveEmptyEntries);
            string MimeHead=String.Empty;
            bool Foundit=false;
            for (int i=0;i<headers.Length;i++)
            {
                if (headers[i].StartsWith("Content-type:", true, null))
                {
                    MimeHead = headers[i];
                    Foundit = true;
                    break;
                }
            }
            if (Foundit)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(prependData);
                sb.Append("\r\n");
                sb.Append(MimeHead);
                sb.Append("\r\n");
                prependByteData = ConvertToBytes(sb.ToString());
            }

               Stream originalStrm            = bodyPart.GetOriginalDataStream();
               Stream strm = null;

               if (originalStrm != null)
               {
                         strm             = new FixMsgStream(originalStrm, prependByteData, appendByteData, resManager);
                         bodyPart.Data    = strm;
                         pc.ResourceTracker.AddResource( strm );
               }
        }

        return inmsg;
    }

Если вы хотите узнать, как вы обрабатываете вложения, см. Этот блог Обработка двоичных документов как сообщений XLANG через BizTalk через веб-службы

Сначала я создал настраиваемый компонент конвейера; Прочтите закодированный MIME документ с помощью BinaryReader в байтовый массив. Обратите внимание, что вы не можете использовать StreamReader, потому что данные в потоке закодированы в base64 и будут содержать символы, отличные от ASCII. Преобразование байтового массива в строку в кодировке Base64 Создайте типизированный XML-документ и добавьте строку кодирования base64 к одному из элементов. Отправьте XML-документ обратно. Код компонента конвейера:

public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(Microsoft.BizTalk.Component.Interop.IPipelineContext pc, Microsoft.BizTalk.Message.Interop.IBaseMessage inmsg)
   {
       var callToken = TraceManager.PipelineComponent.TraceIn(“START PIPELINE PROCESSING”);
       //Assumes inmsg.BodyPart.Data is MIME encoded = base64 encoded           
       BinaryReader binReader = new BinaryReader(inmsg.BodyPart.Data);
       byte[] dataOutAsBytes = binReader.ReadBytes((int)inmsg.BodyPart.Data.Length);
       binReader.Close();
       string dataOut = System.Convert.ToBase64String(dataOutAsBytes);
       TraceManager.PipelineComponent.TraceInfo(“Original MIME part received = ” + dataOut,callToken);
       // THIS IS THE AttachedDoc XML MESSAGE THAT WE ARE CREATING
       //<ns0:AttachedDocument xmlns:ns0=http://BT.Schemas.Internal/AttachedDocument>
       //    <ns0:FileName>FileName_0</ns0:FileName>
       //    <ns0:FilePath>FilePath_0</ns0:FilePath>
       //    <ns0:DocumentType>DocumentType_0</ns0:DocumentType>
       //    <ns0:StreamArray>GpM7</ns0:StreamArray>
       //</ns0:AttachedDocument>
       XNamespace nsAttachedDoc = XNamespace.Get(@”http://BT.Schemas.Internal/AttachedDocument”);
       XDocument AttachedDocMsg = new XDocument(
                                       new XElement(nsAttachedDoc + “AttachedDocument”,
                                       new XAttribute(XNamespace.Xmlns + “ns0″, nsAttachedDoc.NamespaceName),
                                           new XElement(nsAttachedDoc + “FileName”, “FileName_0″),
                                           new XElement(nsAttachedDoc + “FilePath”, “FilePath_0″),
                                           new XElement(nsAttachedDoc + “DocumentType”, “DocumentType_0″),
                                           new XElement(nsAttachedDoc + “StreamArray”, dataOut)
                                           )
                                       );
       dataOut = AttachedDocMsg.ToString();
       TraceManager.PipelineComponent.TraceInfo(“Created AttachedDoc msg = ” + AttachedDocMsg, callToken);
       MemoryStream ms = new System.IO.MemoryStream(System.Text.Encoding.ASCII.GetBytes(dataOut));
       IBaseMessage outmsg = pc.GetMessageFactory().CreateMessage();
       outmsg.Context = pc.GetMessageFactory().CreateMessageContext();
       // Iterate through inbound message context properties and add to the new outbound message
       for (int contextCounter = 0; contextCounter < inmsg.Context.CountProperties; contextCounter++)
       {
           string Name;
           string Namespace;
           object PropertyValue = inmsg.Context.ReadAt(contextCounter, out Name, out Namespace);
           // If the property has been promoted, respect the settings
           if (inmsg.Context.IsPromoted(Name, Namespace))
           {
               outmsg.Context.Promote(Name, Namespace, PropertyValue);
           }
           else
           {
               outmsg.Context.Write(Name, Namespace, PropertyValue);
           }
       }
       outmsg.AddPart(“Body”, pc.GetMessageFactory().CreateMessagePart(), true);
       outmsg.BodyPart.Data = ms;
       pc.ResourceTracker.AddResource(ms);
       outmsg.BodyPart.Data.Position = 0;
       TraceManager.PipelineComponent.TraceInfo(“END PIPELINE PROCESSING”, callToken);
       TraceManager.PipelineComponent.TraceOut(callToken);
       return outmsg;
   }
person Dijkgraaf    schedule 06.10.2013