Site Search:
Sign in | Join | Help

This Blog

Syndication

ASP.NET

Notes, Tricks and Tips on ASP.NET Coding

November 2007 - Posts

  • Trapping errors in an ASP.NET web site

    There are legions of articles (articli?) out there on how to trap errors in ASP.NET. My purpose here is not to be bigger, better, faster. I'm only trying to blog the code that I use, so that I can use it in the next app that I write. So... keep your expectations low <smiles>

    First, add code to the Global.asax:

         Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
            ' Code that runs when an unhandled error occurs
            ExceptionLogger.HandleException(Server.GetLastError().GetBaseException())
            Response.Redirect("~/errorPage.aspx")
        End Sub

     

    Next, add the event handler mentioned above 

    Imports System
    Imports System.Web
    'Imports System.Diagnostics
    'Imports System.Data
    'Imports System.Data.SqlClient
    'Imports System.Web.Mail
    'Imports System.Configuration
    
    
    Public Class ExceptionLogger
    
    
        Public Shared Sub HandleException(ByVal ex As Exception)
            Try
    
    
                Static logExceptions As Boolean = Convert.ToBoolean(System.Web.Configuration.WebConfigurationManager.AppSettings("logExceptions"))
                Dim ofacErrorLog As New dynData.facErrorLog
                Dim ctx As HttpContext = HttpContext.Current
                Dim strData As String = String.Empty
                'Dim eventID As Guid = System.Guid.NewGuid()
                Dim referer As String = String.Empty
                Dim oFunctions As New functions
                Dim sQuery As String = ""
                Dim sForm As String = ""
                Dim logDateTime As String = DateTime.Now.ToString()
    
    
                If Not logExceptions Then Return ' user set web.config setting to false, abort
    
    
                'initialize
                If Not ctx.Request.ServerVariables("HTTP_REFERER") Is Nothing Then
                    referer = ctx.Request.ServerVariables("HTTP_REFERER").ToString()
                End If
    
    
                If Not ctx.Request.Form Is Nothing Then
                    sForm = ctx.Request.Form.ToString()
                End If
    
    
                If Not ctx.Request.QueryString Is Nothing Then
                    sQuery = ctx.Request.QueryString.ToString()
                End If
    
    
                strData = "SOURCE: " & ex.Source & vbCrLf & _
                    "LogDateTime: " & logDateTime & vbCrLf & _
                    "MESSAGE: " & ex.Message & vbCrLf & _
                    "FORM: " & sForm & vbCrLf & _
                    "QUERYSTRING: " & sQuery & vbCrLf & _
                    "TARGETSITE: " & ex.TargetSite.ToString & vbCrLf & _
                    "STACKTRACE: " & ex.StackTrace & vbCrLf & _
                    "REFERER: " & referer
    
    
                'send an email
                oFunctions.sendMail(strData)
    
    
    
                'log the error message
                ofacErrorLog.ConnectionString = System.Web.HttpContext.Current.Session("connect")
    
    
                ofacErrorLog.errorLog_INS(strData, 75000, System.Web.HttpContext.Current.Session("user"))
    
    
            Catch ex2 As Exception
    
    
            End Try
    
    
        End Sub ' end method HandleException
    End Class

     Notice that the Global.asax redirects to a generic 'An Error Has Ocurred' page. Nothing exciting there.

    This code sends an email, and then does a table insert. Both of those topics are covered elsewhere in this blog.

    This is the code for the error page itself

     <%@ Page Language="VB" MasterPageFile="~/MasterPage.master" AutoEventWireup="false"
        CodeFile="errorPage.aspx.vb" Inherits="errorPage" Title="Untitled Page" %>
    
    
    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">
        <div style="text-align: center;">
            <table style="text-align: left; width: 300px">
                <tr>
                    <td>
                        <div class="title1">
                            System Error</div>
                        A crash has occurred.
                    </td>
                </tr>
                <tr>
                    <td style="text-align: center">
                        <asp:AdRotator ID="ar1" runat="server" AdvertisementFile="~/ads.xml" />
                    </td>
                </tr>
                <tr>
                    <td>
                        The error has been logged, and the sys admin has been emailed.
                        <br />
                        <br />
                        If the issue is urgent, please contact the system administrator immediately<br />
                    </td>
                </tr>
            </table>
        </div>
    </asp:Content>
     

    Add this to the web.config file:

      <add key="debug" value="False"/>
      <add key="logExceptions" value="True"/>
      <add key="emailServer" value="mail.myServer.com"/>
      <add key="emailUser" value="something@somewhere.com"/>
      <add key="emailRecipient" value="mrManager@it.com"/>
      <add key="emailPassword" value="secret"/>

    This is the 'ads.xml' file referenced in this page. I use it to rotate a series of photos of auto crashes.

    <Advertisements>
      <Ad>
        <ImageUrl>/images/crash01.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash02.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash03.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash04.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash05.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash06.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash07.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash08.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash09.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
      <Ad>
        <ImageUrl>/images/crash10.jpg</ImageUrl>
        <AlternateText>Oops</AlternateText>
      </Ad>
    </Advertisements>
     

    Last, the images used in the XML file above

    This is the 'error log' class referenced above, and the code to create the table

     CREATE TABLE [_ErrorLog] (
     [intRowID] [int] IDENTITY (1, 1) NOT NULL ,
     [vchrErrorText] [varchar] (1000) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
     [intErrorNum] [int] NOT NULL ,
     [dtCreated] [datetime] NOT NULL CONSTRAINT [DF__ErrorLog_dtCreated] DEFAULT (getdate()),
     [vchrUserID] [varchar] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
    ) ON [PRIMARY]
    GO
    
    
    -- =============================================
    -- 
    -- =============================================
    -- 1/1/1900 created
    IF EXISTS (SELECT name 
        FROM   sysobjects 
        WHERE  name = N'_4P_errorLog_INS' 
        AND    type = 'P')
        DROP PROCEDURE _4P_errorLog_INS
    GO
    
    
    CREATE PROCEDURE _4P_errorLog_INS 
    -- _4P_errorLog_INS 'error', 234, 'steve'
    
    
    @vchrErrorText varchar(1000), 
    @intErrorNum int,
    @vchrUserID varchar(15)
    
    
    AS
     
    INSERT INTO _errorlog (vchrErrorText  , intErrorNum ,vchrUserID ) values (@vchrErrorText, @intErrorNum, @vchrUserID)
    
    
    
    go
    
    
    grant all on _4P_errorLog_INS to public
    
    
    --select * from _errorlog order by introwid desc
    
    
    
     

    Imports System.Data
    Imports Microsoft.ApplicationBlocks.Data
    Imports System.Data.SqlClient
    Public Class facErrorLog
        Dim m_cs As String
        Public Property ConnectionString() As String
            Get
                Return m_cs
            End Get
            Set(ByVal value As String)
                m_cs = value
            End Set
        End Property
        Sub New(ByVal connectionString As String)
            m_cs = connectionString
        End Sub
        Sub New()
        End Sub
    
    
        Sub errorLog_INS(ByVal strErrorText As String, ByVal intErrorNum As Int64, ByVal user As String)
            Try
    
    
                SqlHelper.ExecuteNonQuery(m_cs, CommandType.StoredProcedure, "_4P_errorLog_INS", _
                    New SqlParameter("@vchrErrorText", strErrorText), _
                    New SqlParameter("@intErrorNum", intErrorNum), _
                    New SqlParameter("@vchrUserID", user))
            Catch ex As Exception
                Throw New Exception(ex.Message, ex.InnerException)
    
    
            End Try
    
    
        End Sub
    
    
    End Class

    Here is the 'sendmail' function mentioned above

         Public Sub sendMail(ByVal strBody As String)
    
    
            Try
                Dim strEmailServer As String = System.Web.Configuration.WebConfigurationManager.AppSettings("emailServer")
                Dim strEmailUser As String = System.Web.Configuration.WebConfigurationManager.AppSettings("emailUser")
                Dim strEmailPassword As String = System.Web.Configuration.WebConfigurationManager.AppSettings("emailPassword")
                Dim strEmailRecipient As String = System.Web.Configuration.WebConfigurationManager.AppSettings("emailRecipient")
    
    
                Dim mail As New System.Net.Mail.MailMessage(strEmailUser, strEmailRecipient)
                mail.Subject = "NGB Error"
                mail.Body = strBody
    
    
                Dim serv As New System.Net.Mail.SmtpClient(strEmailServer)
                'serv.Credentials = New System.Net.NetworkCredential(strEmailUser, strEmailPassword)
    
    
                serv.Send(mail)
    
    
            Catch ex As Exception
                'no error handling. we're already in an error loop. If this fails, we're just out of luck
            End Try
    
    
        End Sub

    As always, your comments are welcome

  • Set a default item on a dropdownlist

    Setting a default value on a dropdownlist seems like a simple thing to do... but I never have the exact code when I need it.

    myDdl.Items.FindByValue("myDefaultValue").Selected = true