Gracefully handling exceptions and showing a somewhat informational and yet non-irritating
error message to the end user is very high on my development priority list. Early
in my development career, I used a label control to display my "oops" messages to
users. In addition to that label, I usually ended up with another label for other
more user productive messages, such as when an update was completed.
I wanted a control where I could easily change the theme from error to informational.
I also knew that I wanted the end message to be contained in a neat box, not just
a random, wordy message that appeared at the top of the page. Out of these needs
came my Error Box control. It's light weight, easily expandable, and has the versatility
that I needed without cluttering up my page with different label controls.
The UI of the error box control comes from a user control called ErrorBox.ascx.
The UI is extremely simple and could easily be expanded upon.
ErrorBox.ascx
<div style="margin: 15px 0px 15px 0px;">
<asp:Panel
runat="server"
ID="msgTable"
BackColor="#fff4f1"
BorderColor="Red"
BorderWidth="1"
Width="400px">
<div style="vertical-align: middle;
margin:10px;">
<asp:Label runat="server" ID="lblError" ForeColor="Red" Font-Bold="true"
Text="An error has occurred. The site administrator has been
notified of this error." />
</div>
</asp:Panel>
</div>
By default, the markup above produces the following. Super simple and very easy
to customize further:
The code beind of ErrorBox.ascx contains the many properties of the control that
can be changed when calling the control. Some of these include label text, box color,
box border color, font color, background color, width, and height.
I also include an enum to quick choose a theme - the error theme (red and pink,
like above) or the information theme (light yellow and black text, modeled after
the informatonal Windows popup bubbles.)
C#
public partial
class errbox :
System.Web.UI.UserControl
{
// Declare variables
private
string _ErrorMessage;
private Unit _Width;
private Unit _Height;
private
string _BorderWidth;
private Color _BorderColor;
private Color _BackgroundColor;
private Color _FontColor;
private
bool _FontBold;
private ThemeChoices _ThemeChoices;
/// <summary>
/// Gets or sets the
error message to display.
/// </summary>
public
string ErrorText
{
get {
return _ErrorMessage;
}
set
{
_ErrorMessage
= value;
lblError.Text
= _ErrorMessage;
}
}
/// <summary>
/// Gets or sets the
error message box width. Value cannot be less than 40 pixels or greater than 800
pixels.
/// </summary>
public Unit BoxWidth
{
get {
return _Width;
}
set
{
_Width =
value;
if
(_Width.Value
> 800)
{
throw newApplicationException("Message box width cannot be greater than 800 pixels.");
}
else
if (_Width.Value <
40)
{
throw new ApplicationException("Message box width cannot be less than 40 pixels.");
}
else
{
msgTable.Width
= _Width;
}
}
}
/// <summary>
/// Gets or sets the
error message box height. Value cannot be less than 10 pixels.
/// </summary>
public Unit BoxHeight
{
get {
return _Height ==
20; }
set
{
_Height =
value;
if
(_Height.Value
< 10)
{
throw new ApplicationException("Message box height cannot be less than 20 pixels.");
}
else
{
msgTable.Height
= _Height;
}
}
}
/// <summary>
/// Gets or sets the
error message box border width. Default border value is 1.
/// </summary>
public
int BorderWidth
{
get {
return _BorderWidth;
}
set
{
_BorderWidth
= value;
msgTable.BorderWidth
= _BorderWidth;
if
(_BorderColor ==
null)
{
_BorderColor
= Color.Red;
}
}
}
/// <summary>
/// Gets or sets the
error message box border color. Default value is red.
/// </summary>
public Color BorderColor
{
get {
return _BorderColor;
}
set
{
_BorderColor
= value;
msgTable.BorderColor
= _BorderColor;
if
(_BorderWidth ==
0)
{
msgTable.BorderWidth
= 1;
}
}
}
/// <summary>
/// Gets or sets the
error message box background color. Default color value is salmon.
/// </summary>
public Color BackgroundColor
{
get {
return _BackgroundColor;
}
set
{
_BackgroundColor
= value;
msgTable.BackColor
= _BackgroundColor;
}
}
/// <summary>
/// Gets or sets the
error message box font color. Default color value is red.
/// </summary>
public Color FontColor
{
get {
return _FontColor;
}
set
{
_FontColor =
value;
lblError.ForeColor
= _FontColor;
}
}
/// <summary>
/// Gets or sets the
error message box font weight. Default value is bold.
/// </summary>
public
bool FontBold
{
get {
return _FontBold;
}
set
{
_FontBold =
value;
lblError.Font.Bold = _FontBold;
}
}
// Enum for theme options
public
enum ThemeChoices
{
ErrorTheme,
InformationTheme
}
/// <summary>
/// Gets or sets the
error box theme as a shortcut to specifying other attributes.
/// </summary>
public ThemeChoices BoxTheme
{
get {
return _ThemeChoices;
}
set
{
_ThemeChoices
= value;
switch
(_ThemeChoices)
{
case 0:
// Error theme
msgTable.BackColor =
Color.FromArgb(254,
244, 241);
msgTable.BorderWidth =
1;
msgTable.BorderColor =
Color.Red;
lblError.ForeColor =
Color.Red;
break;
case 1:
// Information theme
msgTable.BackColor =
Color.FromArgb(255,
255, 233);
msgTable.BorderWidth =
1;
msgTable.BorderColor =
Color.Black;
lblError.ForeColor =
Color.Black;
break;
}
}
}
}
VB.NET
Imports System.Drawing
Public MustInherit
Class ErrorBox
Inherits System.Web.UI.UserControl
' Declare variables
Private _ErrorMessage
As String
Private _Width
As Unit
Private _Height
As Unit
Private _BorderWidth
As string
Private _BorderColor
As Color
Private _BackgroundColor As Color
Private _FontColor
As Color
Private _FontBold
As Boolean
Private _ThemeChoices
As ThemeChoices
''' <summary>
''' Gets or sets the
error message to display.
''' </summary>
Public
Property ErrorText()
As String
Get
Return
_ErrorMessage
End
Get
Set(ByVal value As
String)
_ErrorMessage
= value
lblError.Text
= _ErrorMessage
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box width. Value cannot be less than 40 pixels or greater than 800
pixels.
''' </summary>
Public
Property BoxWidth()
As Unit
Get
Return
_Width
End
Get
Set(ByVal value As
Unit)
_Width =
value
If
_Width.Value > 800
Then
Throw New ApplicationException("Message box width cannot be greater than 800 pixels.")
ElseIf
_Width.Value < 40
Then
Throw New ApplicationException("Message box width cannot be less than 40 pixels.")
Else
msgTable.Width
= _Width
End
If
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box height. Value cannot be less than 10 pixels.
''' </summary>
Public
Property BoxHeight()
As Unit
Get
Return
_Height = 20
End
Get
Set(ByVal value As
Unit)
_Height =
value
If
_Height.Value < 10
Then
Throw New ApplicationException("Message box height cannot be less than 20 pixels.")
Else
msgTable.Height
= _Height
End
If
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box border width. Default border value is 1.
''' </summary>
Public
Property BorderWidth()
As Integer
Get
Return
_BorderWidth
End
Get
Set(ByVal value As
Integer)
_BorderWidth
= value
msgTable.BorderWidth
= _BorderWidth
If
_BorderColor = Nothing
Then
_BorderColor
= Color.Red
End
If
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box border color. Default value is red.
''' </summary>
Public
Property BorderColor()
As Color
Get
Return
_BorderColor
End
Get
Set(ByVal value As
Color)
_BorderColor
= value
msgTable.BorderColor
= _BorderColor
If
_BorderWidth = 0
Then
msgTable.BorderWidth
= 1
End
If
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box background color. Default color value is salmon.
''' </summary>
Public
Property BackgroundColor()
As Color
Get
Return
_BackgroundColor
End
Get
Set(ByVal value As
Color)
_BackgroundColor
= value
msgTable.BackColor
= _BackgroundColor
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box font color. Default color value is red.
''' </summary>
Public
Property FontColor()
As Color
Get
Return
_FontColor
End
Get
Set(ByVal value As
Color)
_FontColor =
value
lblError.ForeColor
= _FontColor
End
Set
End
Property
''' <summary>
''' Gets or sets the
error message box font weight. Default value is bold.
''' </summary>
Public
Property FontBold()
As Boolean
Get
Return
_FontBold
End
Get
Set(ByVal value As
Boolean)
_FontBold =
value
lblError.Font.Bold = _FontBold
End
Set
End
Property
' Enum for theme options
Enum ThemeChoices
ErrorTheme
InformationTheme
End
Enum
''' <summary>
''' Gets or sets the
error box theme as a shortcut to specifying other attributes.
''' </summary>
Public
Property BoxTheme()
As ThemeChoices
Get
Return
_ThemeChoices
End
Get
Set(ByVal value As
ThemeChoices)
_ThemeChoices
= value
Select
Case _ThemeChoices
Case 0 ' Error theme
msgTable.BackColor =
Color.FromArgb(254,
244, 241)
msgTable.BorderWidth =
1
msgTable.BorderColor =
Color.Red
lblError.ForeColor =
Color.Red
Case 1 ' Information theme
msgTable.BackColor =
Color.FromArgb(255,
255, 233)
msgTable.BorderWidth =
1
msgTable.BorderColor =
Color.Black
lblError.ForeColor =
Color.Black
End
Select
End
Set
End
Property
End Class
I think that the code is pretty straight forward. Each property has a default value
set in the UI of the ascx file, but you can override the hard coded properties when
you utilize the control in your ASPX properties.
To use the control on an ASPX page, you'll need a register directive and then the
user control. It's easiest to just drag the user control from the solution explorer
to the design view surface in Visual Studio - the register tag and error box tag
will be added automatically for you.
ASPX Markup:
<%@
Register Src="ErrorBox.ascx"
TagName="ErrorBox"
TagPrefix="uc1"
%>
<asp:Content
ID="Content1"
ContentPlaceHolderID="MainContent"
runat="Server">
<uc1:ErrorBox
ID="errBox"
runat="server"
/>
</asp:Content>
For example, if you want to change the box theme to the informational theme but
change the font color and border to a navy blue, just specify the theme and change
the properties you desire:
C#
protected void
Page_Load(object
sender, System.EventArgs
e)
{
errBox.BoxTheme
= ErrorBox.ThemeChoices.InformationTheme;
errBox.FontColor
= Drawing.Color.Navy;
errBox.BorderColor
= Drawing.Color.Navy;
errBox.BoxWidth
= 500;
errBox.ErrorText
= "Post something informative here!";
}
VB.NET
Protected Sub Page_Load(ByVal sender As
Object, ByVal
e As System.EventArgs) Handles
Me.Load
errBox.BoxTheme
= ErrorBox.ThemeChoices.InformationTheme
errBox.FontColor
= Drawing.Color.Navy
errBox.BorderColor
= Drawing.Color.Navy
errBox.BoxWidth
= 500
errBox.ErrorText
= "Post something
informative here!"
End
Sub
And this will be the result:
My main application for the error box is using it as the result of a Catch/Try block
in my code. I place it on the ASPX page and set Visible=False. Then,
in the Catch portion of a Catch/Try block, I will set Visible=True.
Since I already have my generic error message hard coded in the control, that's
all I have to do, except if I want to pass in a more specific error message to the
user.
C#
try
{
// Declare connection string
SqlConnection conn = newSqlConnection(ConfigurationManager.ConnectionStrings("yourConnString").ConnectionString);
// Example SQL Command
SqlCommand comm
=new SqlCommand("SELECT FirstName, LastName FROM Users",
conn);
conn.Open();
// Fill a data table
SqlDataAdapter adapter = new SqlDataAdapter(comm);
DataTable dt
= new DataTable();
adapter.Fill(dt);
adapter.Dispose();
// Clean up
comm.Dispose();
conn.Close();
conn.Dispose();
}
catch
(SqlException ex1)
{
// Catch exceptions (errors)
errBox.Visible
= true;
// Passing in more specific exception information
errBox.ErrorText
= "There was a problem
retrieving your information from the database. Please try again!";
// Alternatively you could use
//errBox.ErrorText = ex1.Message
}
catch
(Exception ex)
{
// Just set error box visibility to true. The control's hard
coded error message will display to user.
errBox.Visible
= true;
// My method to email myself info about the exception
EmailError.emailHandledError(ex);
}
VB.NET
Try
' Declare connection string
Dim
conn As New
SqlConnection(ConfigurationManager.ConnectionStrings("yourConnString").ConnectionString)
' Example SQL Command
Dim
comm As New
SqlCommand("SELECT
FirstName, LastName FROM Users", conn)
conn.Open()
' Fill a data table
Dim
adapter As New
SqlDataAdapter(comm)
Dim
dt As New
DataTable
adapter.Fill(dt)
adapter.Dispose()
' Clean up
comm.Dispose()
conn.Close()
conn.Dispose()
' Catch exceptions (errors)
Catch ex1 As SqlException
errBox.Visible
= True
' Passing in more specific exception information
errBox.ErrorText
= "There was a problem
retrieving your information from the database. Please try again!"
' Alternatively you could use
'errBox.ErrorText = ex1.Message
Catch ex
As Exception
' Just set error box visibility to true. The control's hard coded error message
will display to user.
errBox.Visible
= True
' My method to email myself info about the exception
EmailError.emailHandledError(ex)
End
Try