Click here to Skip to main content
Click here to Skip to main content
Go to top

Sending an HTML-formatted e-mail message from BizTalk

, 5 May 2009
Rate this:
Please Sign up or sign in to vote.
How to send an HTML formatted e-mail from BizTalk.

Introduction

Text emails from BizTalk are really simple to send; you can easily configure the SMTP adapter in BizTalk and send text emails. You can also use the XSLT Transform Pipeline component (BizTalk Server Example) which is a Microsoft sample pipeline component that converts your XML that contains data into HTML. You can use a similar solution by changing the XSL template and extracting the relevant data from your XML. Make sure about the path of your XSL file in the component. For practice, use the same solution until you get your desired HTML output and you are ready to use it in your BizTalk solution.

Well, for rapid development and BizTalk guys who aren't very good with XSL, just like me, would get a lot of trouble. But depending on the scenario, of course after seeing your problem, you can better decide for which solution you want to go. You can explore the above solution on MSDN.

Days back, I wanted to email an error report to my business staff about the TCP messages that failed in a batch. The batch contained about 16000 records and an estimate of 500-1000 records failed in the batch. I wanted to use the solution above but making an XML in my component (yes, I was sending messages to TCP through my .NET component because using the TCP adapter from CodePlex opens and closes the connection each time, and the Tuxedo guy receiving the messages doesn't like that). Well, in the response, I can catch the status and build the error message fields. While each error message has four fields about the customer record, I decided to make a mail template and store it in a string. Then I built the whole mail message at runtime which had the mail message body with error records and stats information, and then I had to mail it through the BizTalk SMTP adapter.

I just return the HTML body in a string from my .NET component to BizTalk Orchestration in which I am building the email message and give it to the SMTP adapter. In BizTalk, as we know, a message can be made of multi message parts, and each message part can have its context. And a whole message which is made up of these parts has its own message context. An email message can have a text/HTML body with attachments. BizTalk translates the email message body as one message part and each attachment as different body parts. Concluding that an email message in BizTalk is a multi-part message. So let's make a multi-part message in BizTalk for email.

multi-part-messages

Multi-part-messages

After creating the multi-part message, you have to configure its type. I made a string which contains the HTML body but didn't configure the message type as String because as you know, sending the String type would convert the message into XML when passing through the pipeline. The message type should be RawString. The RawString type is not in the SDK. You have to build it yourself, compile the class as a separate assembly, GAC it, and add its reference to your project. Then you can configure the message type as RawString. To build the type, the code is shown below. You can find this code on MSDN.

using System;
using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Runtime.Serialization;

using Microsoft.XLANGs.BaseTypes;

namespace Microsoft.Samples.BizTalk.XlangCustomFormatters
{
    public abstract class BaseFormatter : IFormatter
    {
        public virtual SerializationBinder Binder
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }

        public virtual StreamingContext Context
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }

        public virtual ISurrogateSelector SurrogateSelector
        {
            get { throw new NotSupportedException(); }
            set { throw new NotSupportedException(); }
        }

        public abstract void Serialize( Stream stm, object obj );
        public abstract object Deserialize( Stream stm );
    }

    public class RawStringFormatter : BaseFormatter
    {
        public override void Serialize(Stream s, object o)
        {
            RawString rs = (RawString)o;
            byte[] ba = rs.ToByteArray();
            s.Write( ba, 0, ba.Length );
        }

        public override object Deserialize(Stream stm)
        {
            StreamReader sr = new StreamReader( stm, true );
            string s = sr.ReadToEnd();
            return new RawString( s );
        }
    }

    [CustomFormatter(typeof(RawStringFormatter))]
    [Serializable]
    public class RawString
    {
        [XmlIgnore]
        string _val;

        public RawString(string s )
        {
            if (null==s)
                throw new ArgumentNullException();
            _val = s;
        }

        public RawString()
        {
        }

        public byte[] ToByteArray()
        {
            return Encoding.UTF8.GetBytes( _val );
        }

        public override string ToString()
        {
            return _val;
        }
    }
}

After creating the message type, you have to construct the email message. In the message assignment shape, use the following code to construct the message.

EmailMessage.EmailMessageBody = 
  new Microsoft.Samples.BizTalk.XlangCustomFormatters.RawString(EmailStr);

SMTPUtils.Part.SetContentType(EmailMessage.EmailMessageBody,"text/html");
Port_Email(Microsoft.XLANGs.BaseTypes.Address) = 
  "mailto:address@ myenterprisedomain.com ";
EmailMessage(SMTP.Subject) = "IPO Refund process completed";
EmailMessage(SMTP.CC) = "cctosomeone@myenterprisedomain.com";
EmailMessage(SMTP.From) = "fromadd@ myenterprisedomain.com ";
EmailMessage(SMTP.SMTPHost) = "hostname";

Where Port_Email is the send port set to dynamic binding and uses the custom pipeline in which we use the MIME/SMIME Encoder pipeline component. You can drag and drop the MIME/SMIME pipeline component on your custom sendpipeline file in the Encode stage, as shown below.

send_pipeline

You don't have to configure the properties of the component. When configuring the send port, set its binding to dynamic and select the custom send pipeline which you built as below.

Coniguring Dynamic Send Port

After setting up the send port, the SMTPUtils class is also a custom code that has to be compiled as a separate assembly, GAC'd, and you have to add a reference to the assembly in your project. You can find the code to the SMTPUtils class on MSDN.

using System;
using Microsoft.XLANGs; //comes from Microsoft.XLANGs.BaseTypes.dll
using MIME; //comes from Microsoft.Biztalk.GlobalPropertySchemas.dll
 
namespace SMTPUtils
{
  public class Part
  {
    public Part()
    {
    }
    public static void SetContentType(Microsoft.XLANGs.BaseTypes.XLANGPart part, 
                       string contentTypeValue)
    {
      part.SetPartProperty( typeof(Microsoft.XLANGs.BaseTypes.ContentType), contentTypeValue);
    }
    public static void SetFileName(Microsoft.XLANGs.BaseTypes.XLANGPart part, string fileName)
    {
      part.SetPartProperty( typeof(MIME.FileName),  fileName);
    }
    public static System.Xml.XmlDocument SetInfopathForm(
           System.Xml.XmlDocument part, string InfopathFormUrl)
    {
      // Delete existing processing instructions.
      foreach (System.Xml.XmlNode pi in part.SelectNodes(
                      "processing-instruction()"))
      {
        pi.ParentNode.RemoveChild(pi);
      }
      // Add an xml declaration
      System.Xml.XmlDeclaration decl = 
         part.CreateXmlDeclaration("1.0",null,null);
      part.InsertBefore(decl,part.DocumentElement);
      // Create the mso-application procesing instruction.
      System.Xml.XmlProcessingInstruction progid = part.CreateProcessingInstruction(
        "mso-application", "progid='InfoPath.Document'");
      part.InsertBefore(progid, part.DocumentElement);
      // Create the mso-infoPathSolution processing instruction
      System.Xml.XmlProcessingInstruction form = part.CreateProcessingInstruction(
        "mso-infoPathSolution","PIVersion='1.0.0.0' href='" + 
        InfopathFormUrl + "'");
      part.InsertBefore(form,part.DocumentElement);
 
      return part;
    }
  }
}

You can make a separate project for the SMTPUtils and RawString classes and put them in the GAC. This way, you can successfully send HTML formatted email messages through your orchestration. As you are using dynamic binding, you have to do all the configuration in your orchestration and not from your administration console. Try pulling out the email addresses and other things if they tend to change in the future from SSO, or from a database at runtime if you can.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Abdul_Rafay
Architect
Qatar Qatar
I am a BizTalk Server MVP for 2010 and an active blogger and a participant on the MSDN BizTalk Server Forums. I am currently working as a BizTalk Architect at a Bank in Qatar. Before this position I worked as a Sharepoint Consultant in UAE , BizTalk Architect in Bank Saudi Fransi in Saudi Arabia and United Bank Ltd in Pakistan.
 
I also achieved MCTS certification in BizTalk Application development in June 2008.
 
Click here to check out my Blog.

SQL Server Query Notification with BizTalk Server 2009 WCF SQL Adapter.

Envelope Wrapper.

Aggregator (Sequential Convoy)

Splitter (Debatching multiple records)
Scatter and Gather using Self Correlating Port

Comments and Discussions

 
QuestionGetting Error.... PinmemberMember 108679125-Jun-14 20:49 
QuestionRawString Message Type Pinmembermmacwan8317-Nov-11 14:36 
GeneralMy vote of 5 Pinmembermmacwan8317-Nov-11 14:32 
GeneralSending Reports using Biztalk Pinmemberrutup28-Jul-09 20:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140922.1 | Last Updated 5 May 2009
Article Copyright 2009 by Abdul_Rafay
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid