2013-01-03 5 views
0

BizTalk에서 HTTP를 통해 HTTP MIME 요청을 수락해야한다는 요구 사항이 있습니다.BizTalk에서 WCF 서비스를 통해 HTTP를 통한 HTTP MIME 요청을 받아들이는 방법

WCF 게시 마법사를 사용하여 내 스키마를 게시하여 서비스를 만들었으며 SOAP + WSDL Envelope Standard에서 제대로 작동하지만 HTTP/MIME Multipart 메시지에 대해 어떻게 구현합니까?

나는 파이프 라인의 디코드 단계에서 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 

내가 사용할 수 : 여기

_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 메시지입니다 동일한 종점을 가진 동일한 서비스? 그렇다면 모든 서비스를 변경해야합니까?

사용자 지정 파이프 라인 구성 요소를 사용해야합니까?

답변

0

SOAP 수신 봉투가없는 것처럼 수신 포트 유형을 사용하고 BTSHTTPReceive.dll을 사용하고자 할 것입니다. 따라서 기본적으로 WCF를 작동 시키려고하는 것이 아니라 새로운 끝점을 원합니다.

예, 사용자 지정 파이프 라인 구성 요소를 사용해야합니다.

또한 multipart/form-data 인 MIME 메시지를 받고 있으므로 표준 MIME 디코더 파이프 라인 구성 요소를 사용할 수 있도록 메시지에 "MIME-Version : 1.0"을 추가하는 How to process “multipart/form-data” message submitted to BTSHttpReceive.dll을 읽어야합니다. 당신이 첨부 파일을 처리하는 방법에 애호가 얻고 싶은 경우에

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

First I created a custom pipeline component to; Read the MIME encoded document using a BinaryReader into a byte array. Note you cannot use a StreamReader because the data in the stream is base64 encoded and will contain non-ASCII characters. Convert the byte array to a Base64 encoded string Create the typed XML document and add the base64 encode string to one of the elements. Send the XML document back out. The pipeline component code was;

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; 
    } 
를 참조