Since AC suggested I post some sample code for some of the points I was making in my top 5 WCM tips presentation, I've now done just that. In the code you can find examples of the following:
- Exception handler HTTP module - sends notification e-mails when an unhandled exception occurs and redirects the user to a configurable 'friendly' error page
- Custom base class for master page - this is almost a skeleton class since your implementation will vary, but demonstrates how to use a custom base class
- Trace helper class and matching ReSharper templates - for logging what happens in your code (this one's a bonus since I recommend these classes implement trace!)
These files can be downloaded in a Visual Studio project from:
http://sharepointchris.googlepages.com/wcmsamplecode
But for those of you who'd just like a quick look at the code, see below. The actual classes in the project have comments to help you 'use' these things in your site - these have been removed below for readability:
Exception handler HTTP module code:
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;
using System.Web;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using COB.SharePoint.Utilities;
namespace COB.Demos.WcmSamples
{
public class ExceptionHandlerHttpModule : IHttpModule
{
#region -- Private members --
private TraceSwitch traceSwitch = new TraceSwitch("COB.Demos.WcmSamples.ExceptionHandlerHttpModule",
"Trace switch for the COB.Demos.WcmSamples.ExceptionHandlerHttpModule.");
private TraceHelper trace = null;
#endregion
#region -- Constructor
public ExceptionHandlerHttpModule()
{
trace = new TraceHelper(this);
}
#endregion
public void Init(HttpApplication context)
{
context.Error += context_Error;
}
private void context_Error(Object sender, EventArgs e)
{
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "context_Error(): Entered error-handling module.");
// collect the last error..
var exception = HttpContext.Current.Server.GetLastError();
// process it/send e-mail..
processError(exception);
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "context_Error(): Finished handling error, " +
"about to redirect.");
// and finally clear the error and redirect to the friendly error page..
HttpContext.Current.Server.ClearError();
HttpContext.Current.Response.Clear();
string sErrorUrl = ConfigStore.GetValue("Errors", "FriendlyErrorPageUrl");
HttpContext.Current.Response.Redirect(sErrorUrl);
}
private void processError(Exception exception)
{
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "processError(): Entered.");
string sMessage = buildEmailText(exception);
trace.WriteLineIf(traceSwitch.TraceInfo, TraceLevel.Info, "processError(): Built error string '{0}', calling SendEmail.",
sMessage);
sendEmail(sMessage);
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "processError(): Leaving.");
}
private static string buildEmailText(Exception exception)
{
var messageBuilder = new StringBuilder();
messageBuilder.AppendLine("<strong>Date: </strong>" + DateTime.Now);
messageBuilder.AppendLine("<br /><strong>Message: </strong>" + exception.Message);
messageBuilder.AppendLine("<br /><strong>Source: </strong>" + exception.Source);
messageBuilder.AppendLine("<br /><strong>Current user: </strong>" + Thread.CurrentPrincipal.Identity.Name);
messageBuilder.AppendLine("<br /><strong>Machine name: </strong>" + Environment.MachineName);
messageBuilder.AppendLine("<br /><strong>Url: </strong>" + HttpContext.Current.Request.RawUrl);
messageBuilder.AppendLine("<br /><br /><strong>Exception details: </strong>" + exception);
return messageBuilder.ToString();
}
private void sendEmail(String message)
{
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "sendEmail(): Entered.");
try
{
var errorToAddress = ConfigStore.GetValue("Errors", "SendToEmail");
var sErrorSubject = ConfigStore.GetValue("Errors", "EmailSubject");
trace.WriteLineIf(traceSwitch.TraceInfo, TraceLevel.Info,
String.Format("SendEmail(): About to send error e-mail to recipient list '{0}' using SPUtility.SendEmail().",
errorToAddress));
SPUtility.SendEmail(SPContext.Current.Web, false, false, errorToAddress, sErrorSubject, message);
}
catch (Exception exception)
{
var traceMessage = String.Format("Exception thrown attempting to send error e-mail using SPUtility.SendEmail(). " +
"Exception Details: {0}", exception);
trace.WriteLineIf(traceSwitch.TraceError, TraceLevel.Error, String.Format("sendEmail(): {0}", traceMessage));
}
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "sendEmail(): Leaving.");
}
public void Dispose()
{
// nothing to do here..
}
}
}
Skeleton base class for master page:
using System;
using System.Diagnostics;
using System.Web;
using System.Web.UI;
using Microsoft.SharePoint;
namespace COB.Demos.WcmSamples
{
public class BasePage : MasterPage
{
#region -- Private members --
private TraceSwitch traceSwitch = new TraceSwitch("COB.Demos.WcmSamples.BasePage",
"Trace switch for the base page class.");
private TraceHelper trace = null;
#endregion
public BasePage()
{
trace = new TraceHelper(this);
}
protected override void OnLoad(EventArgs e)
{
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "OnLoad(): Entered.");
// TODO: add custom code here..
base.OnLoad(e);
trace.WriteLineIf(traceSwitch.TraceVerbose, TraceLevel.Verbose, "OnLoad(): Leaving.");
}
/// <summary>
/// Showing an example base page property..
/// </summary>
public bool UserIsAuthenticated
{
get { return HttpContext.Current.User.Identity.IsAuthenticated; }
}
}
}
2 comments:
I like this.
Do you know if it is possible to add a httpmodule First using SPWebConfigModification and app.Farm.Services.GetValue...SPWebService...().ApplyWebConfigModifications();
We are not allowed to mess with web.config using notepad so all changes has to be done by code (Farm with 2 frontends, 1 CA and one indexing) ... ;(
Niklas,
I'm pretty sure you can target anything in web.config with SPWebConfigModification since you supply the XPath for the element you wish to add/modify.
So yes, should be possible :-)
Chris.
Post a Comment