SMTP Adapter in BTS2006 and HTML formatted messages

Richard Seroter has a good post here on using the improved SMTP adapter in BizTalk Server 2006 and the options it provides. One question he asks is how to use it to send HTML-formatted messages but using dynamic content, instead of just a static one.

I've managed to do this successfully using our good old RawString friend and multi-part message types. For this, I create a multi-part message type (let's call it EMailType) and adding two parts for it: the first one will hold the email's body (EmailBody, marked with Message Body part=true) and is of type RawString, while the second holds the actual original BizTalk message you want to add as an attachment (let's call it OriginalMessage).

Then, all I have to do is create a new message of type EMailType and initialize it in a message assignment shape like this:

msgbody = new System.Text.StringBuilder();
msgbody.AppendLine("<html><body>");
msgbody.AppendLine("<p>The attached document failed on processing in BizTalk Server.</p>");
msgbody.AppendLine("<p><b>Error details:</b></p><p>");
msgbody.AppendLine("Error Description: <i>" + FailedMessage(ErrorReport.Description) + "</i><br/>");
//msgbody.AppendLine("Message Type: " + FailedMessage(ErrorReport.MessageType) + "<br/>");
msgbody.AppendLine("Error Type: " + FailedMessage(ErrorReport.ErrorType) + "<br/>");
msgbody.AppendLine("Failure Category: " + System.Convert.ToString(FailedMessage(ErrorReport.FailureCategory)) + "<br/>");
msgbody.AppendLine("Failure Code: " + FailedMessage(ErrorReport.FailureCode) + "<br/>");
msgbody.AppendLine("Receive Port Name: " + FailedMessage(ErrorReport.ReceivePortName) + "<br/>");
msgbody.AppendLine("Receive Location: <b>" + FailedMessage(ErrorReport.InboundTransportLocation) + "</b></p>");
msgbody.AppendLine("</body></html>");
EMail.EmailBody = new Microsoft.Samples.BizTalk.XlangCustomFormatters.RawString(msgbody.ToString());
EMail.EmailBody(Microsoft.XLANGs.BaseTypes.ContentType) = "text/html";
EMail.OriginalMessage = FailedMessage;
EMail(SMTP.Subject) = "Failed error message notification";
EMail(SMTP.From) = "someone@somewhere.com";
EMail(SMTP.EmailBodyFileCharset) = "UTF-8";
EMail(SMTP.SMTPHost) = "localhost";
EMail(SMTP.MessagePartsAttachments) = 2;

As you can probably guess, this is an HTML version of the HandlingFailures sample included with BizTalk 2006. The key parts to notice here is how we just create into a StringBuilder the entire HTML message content, construted dynamically. Once that's done, we assign the resulting string to the RawString object in out EmailBody member of the email and set the part's ContentType Context property to "text/html". Do notice we assign the PART's context property, not to the entire message. The second thing to notice is that we configure the SMTP.MessagePartsAttachments context property of the message to 2, which tells the SMTP adapter to use the part marked with Message Body Part=true as the email's body, and attach all remaining parts as message attachments.

You can download the entire example here. Notice you'll need to get the RawString project from the BTS documentation, though. (Speaking of which, I really think RawString should be part of the core BizTalk API, it's too useful not to).

Comments (10)

AarthiMay 19th, 2009 at 6:11 pm

I would really appreciate if you could tell me the link to download the RawString project.
Your help is appreciated a lot.

Tomas RestrepoMay 19th, 2009 at 6:36 pm

Aarthi: The code for RawString is included within the BizTalk server documentation:
http://msdn.microsoft.com/en-us/library/ms962963.aspx

SaschaAugust 19th, 2009 at 1:20 pm

I thought you need a pipeline component with a MIME / SMIME encoder to be able to send mails?

Tomas RestrepoAugust 20th, 2009 at 12:30 pm

@Sasha: No, not in this case. The SMIME encoder is mostly to encrypt/sign messages

ClaudiuMarch 31st, 2010 at 4:57 pm

Hi Tomas. I am battling with this for 2 weeks now. In BizTalk 2006, I receive a text file in my orchestration, the file contains the subject and the body of the email, and I need to attach two PDF files to my email, these files reside on the disk. Most of the work is done; I build my email and send it through a dynamic port. It reaches the destination, but has no attachments. I know it’s not my provider/firewall because I built a C# program to email and the attachments reach their destinations. I could use this class in my orchestration but somehow I feel like using the SMTP capabilities built inside BizTalk (SMTP.Attachments). Any idea where I go wrong? I can send you more details if needed.

ClaudiuMarch 31st, 2010 at 4:58 pm

Forgot to say “Thank you” :-)

Tomas RestrepoMarch 31st, 2010 at 6:30 pm

Claudiu: It’s hard to know what might be wrong without more details, but if I had to guess, I’d say you’re setting the adapter properties wrong. Are you setting SMTP.MessagePartsAttachments = 0?

ClaudiuMarch 31st, 2010 at 11:31 pm

Tomas, sorry for the late reply. This is what I have in my Construct Message/Expression shape:

emailOut.EmailBody = new APRN.CustomMessages.RawString(bodySgm);
emailOut.EmailBody(Microsoft.XLANGs.BaseTypes.ContentType) = “text/html”;
emailOut(SMTP.SMTPHost) = operation.SmtpServer;
emailOut(SMTP.From) = operation.FromEmailAddress;
emailOut(SMTP.EmailBodyFileCharset) = “UTF-8″;
emailOut(SMTP.MessagePartsAttachments) = 2;
emailOut(SMTP.Subject) = subjectSgm;
emailOut(SMTP.Attachments) = attachments;
SendAPRNEmailPort(Microsoft.XLANGs.BaseTypes.Address) = “mailto:” + emailAddress;

The emailOut message is a multi-part message with one part: EmailBody of type RawString. The variables bodySgm, operation.SmtpServer, operation.FromEmailAddress, subjectSgm, attachments and emailAddress are dynamically generated inside my orchestration by various assemblies. Variable ‘attachments’ is of type string and holds something like: ‘C:\file01.pdf|C:\file02.pdf|’.

Tomas, I can provide more details, just let me know. Million thanks for your help.

Tomas RestrepoMarch 31st, 2010 at 11:33 pm

Cliaudiu: Well, you’re setting SMTP.MessagePartsAttachments = 2, which tells it to send extra message parts as attachments (and you have none), so of course it will ignore SMTP.Attachments. Try setting it to 0 instead.

ClaudiuApril 1st, 2010 at 12:06 am

Tomas, that did the trick. That, plus me deleting the MIME Send Pipeline and using a Pass Through.
Thank you Tomas, you rock!

Leave a comment

Your comment