How to process “multipart/form-data” message submitted to BTSHttpReceive.dll

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 

NOTE: This article is migrated from Blog AsiaTech

Date: 2009-8-27 11:05 AM

Orignal URL: https://blogs.msdn.com/b/asiatech/archive/2009/08/27/how-to-process-multipart-form-data-message-submitted-to-btshttpreceive-dll.aspx

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><> 

When use a form based web page as the below to submit a
XML file to one BizTalk HTTP receive location using XMLReceive pipeline, It
would fail to validate and suspended.

<html>

<body>

<FORM NAME="myForm"
ACTION="https://localhost/btarnhttpreceive/btshttpreceive.dll?httpmime"
ENCTYPE="multipart/form-data" METHOD="post">

<INPUT TYPE="file" NAME="myFile"
>

<INPUT TYPE="submit" VALUE="Upload
File" >

</FORM >

</body>

</html>

If check the suspended message, you would see the message
format similar as the below:

-----------------------------7d91593580102

Content-Disposition: form-data; name="myFile";
filename="D:\HttpMimeTest\1.xml"

Content-Type: text/xml

<ns0:TestRoot
xmlns:ns0="https://HttpMimeTest.Schema1">

<TestRecord>

<TestField>TestField_0</TestField>

</TestRecord>

</ns0:TestRoot>

-----------------------------7d91593580102—

It looks like a MIME encoded message, but if develop a
customized pipeline which add a MIME/SMIME decoder before the XML disassembler,
it would fail to decode the message since actually the format is not
complete/standard MIME format.

Solution:

Develop a pipeline component which is added before the
MIME/SMIME decoder at the same stage, the component would add the missed MIME
header as the below to the beginning of an incoming message to construct a
complete MIME message so the MIME/SMIME decoder can decode it, retrieve the
packed XML and pass it to the XML disassembler at the next stage in the
pipeline.

MIME-Version: 1.0

Content-Type: multipart/form-data;
boundary=---------------------------7d91593580102

The FixMsg pipeline component sample which is located at
the folder [BizTalk Installation Folder] \
SDK\Samples\Pipelines\CustomComponent\FixMsg can be used to add a fixed
preconfigured string to the beginning of a message. It has to be modified in
order to add a dynamic string such as boundary part as the above. The trick is
the Content-Type including boundary can be retrieved from the incoming message
context property InboundHttpHeaders. The following is the demo modified
function Execute in the FixMsg.cs which read the Content-Type head with
boundary from the context property InboundHttpHeaders and then append it to the
preconfigured prependData which is “MIME-Version: 1.0”.

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",
"https://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;

}

The following is the screen capture for the customized
pipeline project.


  
  
  
  
  
  
  
   
  
  
  

 
 

Regards,

XiaoDong Zhu