【问题标题】:how to accept Http MIME request over HTTP through a WCF service in BizTalk如何通过 BizTalk 中的 WCF 服务通过 HTTP 接受 Http MIME 请求
【发布时间】:2012-12-18 09:10:45
【问题描述】:

我需要在 BizTalk 中通过 HTTP 接受 HTTP MIME 请求。

我通过使用 WCF 发布向导发布我的架构创建了一个服务,它适用于 SOAP+WSDL 信封标准,但我如何为 HTTP/MIME 多部分消息实现相同的功能?

我尝试在管道的解码阶段提供 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 

我可以通过相同的端点使用相同的服务吗?如果是这样,我必须对我的服务进行哪些更改?

我必须使用任何自定义管道组件吗?

【问题讨论】:

    标签: wcf biztalk wcf-binding biztalk-2010 biztalk-2009


    【解决方案1】:

    您将需要一个 HTTP 类型的接收端口并使用 BTSHTTPReceive.dll,因为它看起来没有 SOAP 信封。所以你基本上想要一个新的端点,而不是试图让 WCF 工作。

    是的,您必须使用自定义管道组件。

    此外,当您收到多部分/表单数据的 MIME 消息时,您需要阅读 How to process “multipart/form-data” message submitted to BTSHttpReceive.dll,它将“MIME-Version: 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;
        }
    

    如果您想更了解如何处理附件,请参阅此博客 Processing Binary Documents as XLANGMessages Through BizTalk Via Web Services

    首先我创建了一个自定义管道组件;读取 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;
       }
    

    【讨论】:

      猜你喜欢
      • 2013-02-10
      • 1970-01-01
      • 2017-05-10
      • 2019-01-30
      • 2012-03-23
      • 2011-05-29
      • 2010-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多