Keep your web editors in the loop!

For us as developers it’s important to log errors that occur on a website. We do this in ASP.NET and  EPiServer through either debugging during the development phase, or implementning log management through writing to the event log or utilizing log4net.

puzzle This post is about letting web editors know that something has gone wrong, and what they can do to resolve the error. Parallell to this we do not wish to display a full error message for website visitors. They should be made aware why the page isn’t working, but not given any specifics.

The scenario

Let’s say you’ve just created a website using EPiServer CMS. The website implements an RSS-reader page. The web editor might enter a feed address which is not valid which generates an error. We do not wish to display the full error message for any visitors that browse the feed page. The web editors, however, should be alerted that everything is not well in web land and what might be the cause of this.

We need to implement the following functionality:

  • Check if the current user is a web editor
  • Display the full error message only if the current user has the appropriate permission set

Is the current user a web editor?

Through the ASP.NET provider model and the PrincipalInfo class in EPiServer.Security we can check if the current user has edit permission to the page.

bool hasEditAccess = EPiServer.Security.PrincipalInfo.HasEditAccess;

This enables us to modify the error message according to the user’s access level.

if(hasEditAccess)
    errorMessageControl.Text = "Failed to retrieve the feed!";
else
    errorMessageControl.Text = 
		String.Concat("Failed to retrieve the feed because ", 
			webException.Message);

Let’s package it!

Duplicating code is never good practice. So let’s have a look at how we could package this into a simple server control.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EPiServer;
using EPiServer.Security;
using System.Web.UI.HtmlControls;

namespace DBLOG.EPiServerCMS6.Controls
{
    /// <summary>
    /// EPiServer CMS web control that displays an error message 
    /// corresponding to the user's access level
    /// </summary>
    public class ErrorMessage : UserControlBase
    {
        public string CssClass { get; set; }

        /// <summary>
        /// Sets the error message that is displayed for website visitors
        /// </summary>
        public string ErrorTextEveryone { get; set; }

        /// <summary>
        /// Sets the error message that is displayed 
        /// for website editors and administrators
        /// </summary>
        public string ErrorTextWebEditor { get; set; }

        protected override void OnLoad(EventArgs e)
        {
        base.OnLoad(e);

        // Create a div tag in which the error message will be set
        HtmlGenericControl div = new HtmlGenericControl("div");

        // Determine if the current user 
        // has editorial or adminstrative access rights
        if (PrincipalInfo.HasEditAccess || PrincipalInfo.HasAdminAccess)
            div.InnerText = this.ErrorTextWebEditor ?? String.Empty;
        else
            div.InnerText = this.ErrorTextEveryone ?? String.Empty;

        // Add the class attribute to the generic 
        // html contol if the property CssClass has been set
        if (!String.IsNullOrEmpty(this.CssClass))
            div.Attributes.Add("class", this.CssClass);

        // Check if any actual error text has been set
        bool errorTextSet = !String.IsNullOrEmpty(div.InnerText);

        // Only add the error message control 
        // if it has something to display!
        if (errorTextSet)
            this.Controls.Add(div);
        }
    }
}

To use the control on a page you'll need to use the Register page directive.

<%@ Register Namespace="DBLOG.EPiServerCMS6.Controls" 
	TagPrefix="DBLOG" 
		Assembly="DBLOG.EPiServerCMS6.Website" %>

On the page you add it like an ordinary control.

<DBLOG:ErrorMessage ID="errorMessage" CssClass="error-message" runat="server" />

You can either set the error message in markup or in the code-behind file. In this scenario I’m catching an WebException when the RSS-feed cannot be loaded.

catch (WebException webEx)
{
    errorMessage.ErrorTextEveryone = "Could not load feed.";

    errorMessage.ErrorTextWebEditor = String.Concat("Could not load feed because: ", webEx.Message);
}

The result

And here is what it'll look like if the RSS-feed URL is incorrect and a visitor browses the page.

 image

And when an administrator or web editor views the page (granted they’re logged in, of course!) the result is slightly different.

 image

blog comments powered by Disqus