This is the third post in a series. The first post described the problem: ASP.NET wasn't reporting inner exception stack traces. The second post described my solution. This post shows the code I used to solve the problem: a custom email provider for the Health Monitoring system in ASP.NET. Enjoy! Here's the provider. Note that I opted *not* to build a buffering provider to keep things simple: public class MyMailWebEventProvider : WebEventProvider { string to; string from; string subjectPrefix; public override void Initialize( string name, NameValueCollection config) { base .Initialize(name, config); to = GetAndRemoveStringAttribute(config, "to" , true ); from = GetAndRemoveStringAttribute(config, "from" , true ); subjectPrefix = GetAndRemoveStringAttribute(config, "subjectPrefix" , false ); } public override void ProcessEvent(WebBaseEvent raisedEvent) { SendMail(raisedEvent); } private void SendMail(WebBaseEvent raisedEvent) { string subject = ComputeEmailSubject(raisedEvent); string body = ComputeEmailBody(raisedEvent); MailMessage msg = new MailMessage(from, to, subject, body); new SmtpClient().Send(msg); } private string ComputeEmailBody(WebBaseEvent raisedEvent) { WebRequestErrorEvent errorEvent = raisedEvent as WebRequestErrorEvent; if ( null != errorEvent) return ErrorEventFormattingHelper.FormatRequestErrorEvent(errorEvent); else return raisedEvent.ToString(); } private string ComputeEmailSubject(WebBaseEvent raisedEvent) { StringBuilder subjectBuilder = new StringBuilder(); // surface some details in subject about error events WebBaseErrorEvent errorEvent = raisedEvent as WebBaseErrorEvent; if ( null != errorEvent) { Exception unhandledException = errorEvent.ErrorException; // drill through reflection exceptions to show the root cause TargetInvocationException invocationException = unhandledException as TargetInvocationException; if ( null != invocationException) { Exception innerException = DrillIntoTargetInvocationException(invocationException); subjectBuilder.AppendFormat( "{0}" , (innerException ?? invocationException).GetType().Name); if ( null != innerException) subjectBuilder.Append( " (via reflection)" ); } else subjectBuilder.Append(unhandledException.GetType().Name); } // if we've not got anything better // just show the event type in the subject if (0 == subjectBuilder.Length) subjectBuilder.AppendFormat( "Event type: {0}" , raisedEvent.GetType().Name); if (! string .IsNullOrEmpty(subjectPrefix))
Read More...