Using MIME Encoder Pipeline component
Recently I had a situation where I need to upload files from BizTalk Server via HTTP in MIME format.
For all those who are new to MIME, it is a standard (basically a particular message format) that is primarily used for exchanging emails (Body + Multiple file attachments). Below is one sample MIME message.
• HTTP Header
• Mime Header which indicates a boundary
• Body Part (Some text)
• File Attachments (base64 or any other encoded format)
BizTalk out of box provides us with MIME Encoder pipeline component to generate this kind of MIME message.
This component internally uses Virtual Stream to generate MIME message structure. Below is the quick look of the properties of this Component. This MIME Encoder also provides options to encrypt the content. It can be selected optionally.
BizTalk has Multipart messages mainly to support this feature.
To generate this MIME message, we need to create a multipart message. This can be done inside an Orchestration or a Pipeline.
While creating this multipart message, I am going to attach the file stream directly to the Message Part. This way, it will not load the file into memory. Here is one sample on how we do this.
1. Creating a multipart message in an Orchestration.
a. Create a class library with the sample code given in here
b. Define a multi part message in your orchestration. For the attachments, set the type as System.Xml.XmlDocument.
c. Use expression shape to make a call to class library and attach the file message part to the actual message.
d. Completed orchestration will look like below.
When this multipart message passes through MIME Encoder, it generates a MIME message as shown in beginning of the post.
2. If you are not using an orchestration, you can even use a pipeline component to add a part to the message. Below is the sample code to do it.
By using any of the above two ways we can create multipart messages and these can be utilized by MIME encoder to generate MIME Messages
However, I observed that though MIME encoder does not load the whole file attachment into memory, BTSNTSvc process is still eating up lot of memory especially for larger files of >300 MB. I thought of one another way which would be better in consuming resources.
In the Receive pipeline, I constructed MIME messages using c# code and used HttpWebRequest method to make a call to the Service directly using Buffered streaming approach. This way, I am not going to use HTTP Adapter. Rather, I am reading large file part by part and pushing it to the stream using HttpWebRequest methods.
Here is some sample code.
Based on the web response, receive pipeline will construct a success/failure message and pushes it to message box.
Note: MIME Encoder works only with BizTalk 32 bit hosts (even in BizTalk 2013). If you try to use 64 bit, you will encounter a strange error.