Tuesday, November 15, 2005

Biztalk 2004: Mime revisited ...

I had to deploy a flow in production today that has been working fine for 2 months in our test environment. The flow receives a mail from an IIS maildrop folder, gets all attachments and sends them to an orchestration. Mails are in .eml format which is actually a mime message following the RFC2557 specification.
Below you can find a sample file that enters Biztalk:

From: a@a.com
To: b@b.com
Subject: hello world
Date: Mon, 14 Nov 2005 23:31:17 -0000
MIME-Version: 1.0
Content-Type: multipart/mixed;
boundary="----_=_NextPart_000_01C5E973.82A5C520"

------_=_NextPart_000_01C5E973.82A5C520
Content-Type: multipart/alternative; boundary=
"----_=_NextPart_001_01C5E973.82A5C520"

------_=_NextPart_001_01C5E973.82A5C520
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

hello world, content

------_=_NextPart_001_01C5E973.82A5C520
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: 7bit


<HTML>
<HEAD>
<TITLE>hello world</TITLE>
</HEAD>
<BODY>hello world, content</BODY>
</HTML>

------_=_NextPart_001_01C5E973.82A5C520--
------_=_NextPart_000_01C5E973.82A5C520
Content-Type: text/plain; name="test.txt"
Content-Disposition: attachment; filename="test.txt"

text in attachment

------_=_NextPart_000_01C5E973.82A5C520--

After decoding the above message we have one IbaseMessage having multiple IBaseMessagePart objects.
In my pipeline component I always assumed that the actual body of the mail was a BodyPart and the attachments were all the other parts. I guess I was wrong. In the above sample, the BodyPart contains the attachment.
So how can we make sure that only the attachments are sent to Biztalk and not the body of the mail? Below is the solution:

        /// <summary>

        /// Try to determine if the message part is an attachment or not.

        /// Attachments will always have a file name in the mime property

        /// namespace.

        /// </summary>

        /// <param name="messagePart"></param>

        /// <returns></returns>

        private bool IsAttachment(IBaseMessagePart messagePart)

        {

            if (messagePart == null)

            { // bail if message part is empty

                return false;

            }

 

            /*

            * Read the file name from the mime property namespace.

            */

            string fileName = messagePart.PartProperties.Read("FileName","http://schemas.microsoft.com/BizTalk/2003/mime-properties") as string;

            if (fileName != null && fileName.Length > 0)

            {

                return true;

            }

            return false;

        }


In our pipeline component (disassemble stage), we will only disassemble messages that have the FileName-property set in the mime properties namespace.
Ok, I have to admit, no rocket-science here, but maybe there are people that will find this helpful.

No comments: