Skip to content

Instantly share code, notes, and snippets.

@ianfnelson
Last active August 29, 2015 13:57
Show Gist options
  • Save ianfnelson/9842679 to your computer and use it in GitHub Desktop.
Save ianfnelson/9842679 to your computer and use it in GitHub Desktop.
Code for 2004 blog post "Custom Email Publisher for Microsoft Exception Management Application Block"
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Reflection;
using System.Text;
using System.Web.Mail;
using Microsoft.ApplicationBlocks.ExceptionManagement;
namespace IanFNelson
{
/// <summary>
///
/// This is a custom exception publisher which sends email alerts.
///
/// The following custom settings can be configured in the publisher section of the application config file:
///
/// mailTo: Distribution list of email recipients
/// mailFrom: Originator email address
/// mailSubject: Subject header of email
/// mailServer: SMTP server address
/// mailPriority: System.Web.Mail.MailPriority setting - i.e. (0 = Normal, 1 = Low, 2 = High)
///
/// </summary>
public class EmailPublisher : IExceptionPublisher
{
// Local variables - to be obtained via configSettings (change these defaults)
private string _mailTo = "email@domain.com";
private string _mailFrom = "email@domain.com";
private string _mailBCC = "";
private string _mailCC = "";
private string _mailSubject = "Application Exception Alert";
private string _mailServer = "127.0.0.1";
private MailPriority _mailPriority = MailPriority.Normal;
/// <summary>
/// Boring default constructor
/// </summary>
public EmailPublisher()
{
}
#region IExceptionPublisher Members
/// <summary>
/// Publish an exception via email
/// </summary>
/// <param name="exception">The Exception</param>
/// <param name="additionalInfo">Additional Information</param>
/// <param name="configSettings">Configuration Settings</param>
public void Publish(Exception exception, System.Collections.Specialized.NameValueCollection additionalInfo, System.Collections.Specialized.NameValueCollection configSettings)
{
#region Obtain Config Values if provided
if (configSettings != null)
{
// mailTo
if (configSettings["mailTo"] != null && configSettings["mailTo"].Length > 0)
{
_mailTo = configSettings["mailTo"];
}
// mailFrom
if (configSettings["mailFrom"] != null && configSettings["mailFrom"].Length > 0)
{
_mailFrom = configSettings["mailFrom"];
}
// mailBCC
if (configSettings["mailBCC"] != null && configSettings["mailBCC"].Length > 0)
{
_mailBCC = configSettings["mailBCC"];
}
// mailCC
if (configSettings["mailCC"] != null && configSettings["mailCC"].Length > 0)
{
_mailCC = configSettings["mailCC"];
}
// mailSubject
if (configSettings["mailSubject"] != null && configSettings["mailSubject"].Length > 0)
{
_mailSubject = configSettings["mailSubject"];
}
// mailServer
if (configSettings["mailServer"] != null && configSettings["mailServer"].Length > 0)
{
_mailServer = configSettings["mailServer"];
}
// mailPriority
if (configSettings["mailPriority"] != null && configSettings["mailPriority"].Length > 0)
{
try
{
_mailPriority = (MailPriority)Convert.ToInt32(configSettings["mailPriority"]);
}
catch
{
_mailPriority = MailPriority.Normal;
}
}
}
#endregion
#region Build email body
StringBuilder strBody = new StringBuilder("<html><body>");
strBody.Append("<style>");
strBody.Append("body * {font-family:Verdana,Arial,sans-serif;font-size:10px;text-align:left;vertical-align:top}");
strBody.Append("h6 {font-size:12px;text-align:left;text-decoration:underline;font-weight:bold;}");
strBody.Append("</style>");
#region Record Contents of AdditionalInfo collection
if (additionalInfo != null)
{
strBody.Append("<h6>General Information</h6>");
strBody.Append("<table>");
foreach (string i in additionalInfo)
{
strBody.AppendFormat("<tr><td>{0}</td><td>{1}</td>", i, additionalInfo.Get(i));
}
strBody.Append("</table>");
}
#endregion
if (exception == null)
{
strBody.Append("No Exception object has been provided.");
}
else
{
#region Loop through each exception class in the chain of exception object
Exception currentException = exception; // Temp variable to hold InnerException object during the loop.
int intExceptionCount = 1; // Count variable to track the number of exceptions in the chain.
do
{
// Write heading
strBody.AppendFormat("<h6>{0}) {1}</h6>", intExceptionCount.ToString(), currentException.GetType().FullName);
strBody.Append("<table>");
#region Loop through the public properties of the exception object and output their values
PropertyInfo[] aryPublicProperties = currentException.GetType().GetProperties();
NameValueCollection currentAdditionalInfo;
foreach (PropertyInfo p in aryPublicProperties)
{
// Don't log info for the InnerException or StackTrace (do StackTrace last - bit neater).
if (p.Name != "InnerException" && p.Name != "StackTrace")
{
if (p.GetValue(currentException, null) == null)
{
strBody.AppendFormat("<tr><td>{0}</td><td>NULL</td></tr>", p.Name);
}
else
{
// If exception type is a BaseApplicationException, loop through the collection of AdditinoalInfo
if (p.Name == "AdditionalInformation" && currentException is BaseApplicationException)
{
// Verify the collection is not null
if (p.GetValue(currentException, null) != null)
{
// Cast the collection into a local variable
currentAdditionalInfo = (NameValueCollection)p.GetValue(currentException, null);
// Check if the collection contains values.
if (currentAdditionalInfo.Count > 0)
{
strBody.AppendFormat("{0}AdditionalInformation:", Environment.NewLine);
// Loop through the collection adding the information to the string builder.
for (int i = 0; i < currentAdditionalInfo.Count; i++)
{
strBody.AppendFormat("<tr><td>{0}</td><td>{1}</td></tr>", currentAdditionalInfo.GetKey(i), currentAdditionalInfo[i]);
}
}
}
}
// Otherwise just write the ToString() value of the property
else
{
strBody.AppendFormat("<tr><td>{0}</td><td>{1}</td></tr>", p.Name, p.GetValue(currentException, null));
}
}
}
}
#endregion
if (currentException.StackTrace != null)
{
strBody.AppendFormat("<tr><td>StackTrace</td><td>{0}</td></tr>", currentException.StackTrace);
}
strBody.Append("</table>");
// Reset the temp exception object and iterate the counter
currentException = currentException.InnerException;
intExceptionCount++;
} while (currentException != null);
#endregion
}
strBody.Append("</body></html>");
#endregion
// Send email
MailMessage _mail = new MailMessage();
_mail.To = _mailTo;
_mail.From = _mailFrom;
_mail.Cc = _mailCC;
_mail.Bcc = _mailBCC;
_mail.Subject = _mailSubject;
_mail.Priority = _mailPriority;
_mail.Body = strBody.ToString();
_mail.BodyFormat = MailFormat.Html;
SmtpMail.SmtpServer = _mailServer;
SmtpMail.Send(_mail);
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment