Before starting this post, let me discuss the requirements and the scenario when this is going to help.
In many cases in BizTalk, we used SMTP port to send the messages to notify users. Either we are attaching the message as an attachment or we are sending the messages in a body. In our case, we have to query the SQL Server log messages, pull out the error messages and send the daily report in a formatted way to the concerned users. For this, we have created a custom pipeline component. The below image is the basic flow:
The below custom component will format the message into HTML table using Linq and send the formatted output to the user within the email body.
Custom Pipeline Code
public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage pInMsg)
{
IBaseMessagePart bodyPart = pInMsg.BodyPart;
IBaseMessageContext context = pInMsg.Context;
MemoryStream messageStream;
Byte[] messageBytes;
if (bodyPart != null)
{
try
{
Stream originalMessageStream = pInMsg.BodyPart.GetOriginalDataStream();
byte[] bufferOriginalMessage = new byte[originalMessageStream.Length];
originalMessageStream.Read(bufferOriginalMessage, 0, Convert.ToInt32(originalMessageStream.Length));
string originalDataString = System.Text.ASCIIEncoding.ASCII.GetString(bufferOriginalMessage);
XDocument dataDoc = XDocument.Parse(originalDataString);
List<XElement> newtableElements =
dataDoc.Root.Elements().Elements().Elements().Elements().Elements().ToList();
XElement table = new XElement("table",
new XElement("thead",
new XElement("tr",
new XElement("th", "Any ID"),
new XElement("th", "Message"),
new XElement("th", "Any Message"))));
foreach (XElement element in newtableElements)
{
if (element.Name == "NewTable")
{
XElement record = new XElement("tbody",
new XElement("tr",
new XElement("td", element.Element("LogID").Value),
new XElement("td", element.Element("Message").Value),
new XElement("td", element.Element("FormattedMessage").Value)));
table.Add(record);
}
}
messageBytes = Encoding.UTF8.GetBytes(table.ToString());
messageStream = new MemoryStream(messageBytes.Length);
messageStream.Write(messageBytes, 0, messageBytes.Length);
messageStream.Position = 0;
bodyPart.Data = messageStream;
bodyPart.ContentType = "text\html";
return pInMsg;
}
catch (Exception ex)
{
throw new ApplicationException(ex.Message);
}
}
return pInMsg;
}