Click here to Skip to main content
12,507,173 members (63,939 online)
Click here to Skip to main content
Articles » Web Development » ASP.NET » General » Revisions
Add your own
alternative version

Stats

45.6K views
969 downloads
42 bookmarked
Posted

Custom Exception Framework:Using Enterprise Library Exception Handling Block

, 30 Oct 2008 CPOL
Rate this:
Please Sign up or sign in to vote.
This article demonstrate the working model of Custom Exception block using Enterprise Library Exception Handling Block which is build around MVP architecture.
This is an old version of the currently published article.

Introduction

This article demonstrate the creation of custom Exception Layer using Microsoft Enterprise library Exception Handling block. The demo created in this article has Model View Presenter architecture with custom Exception layer build in it.

System Requirement

  • Install Microsoft Enterprise Library .Net 2.0
  • .Net framework 2.0

    Important Namespace

  • Using Microsoft.Practices.EnterpriseLibrary.ExceptionHandling
  • Microsoft.Practices.EnterpriseLibrary.Common.dll
  • Microsoft.Practices.ObjectBuilder.dll
  • Microsoft.Practices.EnterpriseLibrary.Common.dll
  • System.Collections.Specialized.dll
  • System.Configuration.Assemblies.dll
  • Features Of Custom Exception Block

    1. The custom block partitioned the exception based on layers .For E.g. Data Access Layer Exception, Presenter Layer Exception, Service Layer Exception and So on.
    2. This Custom Exception also target the system layer exception like Critical Exception .For example :Database server is down. Web service Unavailable! and so on
    3. This Custom exception also address the exception that is handled and custom messages to be shown to user. For e.g. Insert duplicate record in database, exception thrown from database and this handled in .net application and bubbled up to show user defined warning Message. So this eventually separate the warnings, error and exception. If unhandled system error ,the system is redirected to error page. If warning or operational information ,it is shown on the same functional screen ,so that normal execution is not stopped.
    4.  This block is integrated with Model View Presenter Architecture.

       

    Configuration Setting

    The configuration settings encapsulates various policies required for the application. The policies are

    1. Global Policy: Identifies the actual exception that comes from the layers.
    2. Propagate Policy : This policy propagate the actual exception thrown from layers to mainstream.
    3. Custom Policy :Presenter/Data Access/View /Service

    SR. Policy Post Handling Action Layer
    1 Global None Project.Practice.MVP.ExceptionHandling
    2 Propagate  NotifyReThrow System.Exception
    3 Custom: Presenter Layer ThrowNewException Project.Practice.MVP.Presenter
    4 Custom: Data Access Layer ThrowNewException Project.Practice.MVP.DataAccess
    5 Custom: View Layer ThrowNewException Project.Practice.MVP.Web

    Configuration

    Configuration

    Configuration

    Configuration

    Configuration

    Configuration

    Project.Practice.MVP.ExceptionHandling: Custom Exception Class

    The physical representation of exceptionahndling class with MVP model is as shown below.

    Configuration

    The below class diagram depicts the picture of exception handling class construct. All the layers custom exception class are created. These class in turns inherit Base Exception class.

    Configuration

    Project.Practice.MVP.ExceptionHandling: ApplicationExceptionHandler.cs

    In this class we have method called HandleException which implements the interface method IExceptionHandler.

    namespace Project.Practice.MVP.ExceptionHandling
    {
        [ConfigurationElementType(typeof(CustomHandlerData))]
        public class ApplicationExceptionHandler : IExceptionHandler
        {
            private const string UNEXPECTED_ERROR = "Unexpected Error!!";
            public ApplicationExceptionHandler(NameValueCollection ignore)
            {
    
            }
            #region IExceptionHandler Members
            public Exception HandleException(Exception exception, Guid correlationID)
            {
                try
                {
                    /* This is Critical Layer Exception.
                    For E.g Database Unavailable
                    Web Service Unavailable and so on .*/
                   
                    if (exception.GetType().Equals(typeof(CustomException.CriticalException)))
                    {
                        if (HttpContext.Current.Items.Contains("ERROR_MSG"))
                        {
                            HttpContext.Current.Items.Remove("ERROR_MSG");
                        }
                        HttpContext.Current.Items.Add("ERROR_MSG", exception.Message);
                        HttpContext.Current.Server.Transfer("~/CriticalException.aspx", false);
                    }    
                    //This is Presenter Layer Exception.
                    else if (exception.GetType().Equals(typeof(CustomException.PresenterLayerException)))
                    {
    
                        if ((CustomPage)HttpContext.Current.Handler != null)
                        {
                            ((CustomPage)HttpContext.Current.Handler).Error 
    
    = "Presenter Layer Exception :" + exception.InnerException.Message ;                                         
                        }
                    }
                    //This is View Layer Exception.
                    else if (exception.GetType().Equals(typeof(CustomException.ViewLayerException)))
                    {
                        if ((CustomPage)HttpContext.Current.Handler != null)
                        {
                            ((CustomPage)HttpContext.Current.Handler).Error 
    ="View Layer Exception:" + exception.Message;                     
                         }
                    }
                    //This is DataAccess Layer Exception
                    else if (exception.GetType().Equals(typeof(CustomException.DataAccesLayerException)))
                    {
                        if ((CustomPage)HttpContext.Current.Handler != null)
                        {                      
                            ((CustomPage)HttpContext.Current.Handler).Error 
    = "DataAccess Layer Exception: "+ exception.Message;
                        }
                    }
                    //This is SQL DAL Layer Exception
                    else if (exception.GetType().Equals(typeof(CustomException.SQLDALException)))
                    {
                        if ((CustomPage)HttpContext.Current.Handler != null)
                        {
                            ((CustomPage)HttpContext.Current.Handler).Error = "SQL Error 101: " + exception.Message;
                        }
                    }
                    else
                    {
                        if ((CustomPage)HttpContext.Current.Handler != null)
                        {
                           //This is Session Expired Exception
                            if ((((CustomPage)HttpContext.Current.Handler).CurrentSession == null))
                            {
                                HttpContext.Current.Items["ERROR_MSG"] = "Access Denied";
                                HttpContext.Current.Server.Transfer("~/CriticalException.aspx", false);
                            }
                            //This is General Exception:UN_DEFINED EXCEPTION
                            HttpContext.Current.Server.Transfer("~/CriticalException.aspx", false);
                        }
                    }
                }
                catch (System.Threading.ThreadAbortException ex)
                {
                }
                catch (Exception ex)
                {
                }
                return exception;
            }
    
            #endregion
        }
    }
    

    Project.Practice.MVP.ExceptionHandling: ExceptionHandleProvider.cs

    This is called from web pages where exception get bubbled up.

    namespace Project.Practice.MVP.ExceptionHandling
    {
        public class ExceptionHandleProvider
        {
            public static bool HandleException(Exception exception, string PolicyName)
            {
                bool reThrow = false;
                reThrow = ExceptionPolicy.HandleException(exception, PolicyName);
                return reThrow;
            } 
        }
    }

    Project.Practice.MVP.DataAccess:DataProvider

    This is partial class. As we have partial class named 'DataProvider' with different file name for each module. In this method if the exception is Critical Exception in DataAccesslayer it will be propagate across layer to display Critical Exception but there is dataAccess exception then this will get propagate through other layers to display DataAccessLayer Exception.

    namespace Project.Practice.MVP.DataAccess
    {
        public partial class DataProvider
        {
            public static void ProcessDataAccessLayerException(Exception ex)
            {
                bool reThrow = false;
                if (ex.GetType().Equals(typeof(CriticalException)) == true)
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else if (ex.GetType().Equals(typeof(SQLDALException)) == true)
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "DataAccess Layer Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
    
            } 
    
        }
    }

    Now we have partial class DataProvider with file module name as MathOperationDataProvider.cs.

    DataAccess:Raise Exception

    namespace Project.Practice.MVP.DataAccess
    {
        public partial class DataProvider
        {
            /// <summary>
            /// Get DemandList 
            /// </summary>
            /// <returns></returns>
            public static int AddOperation(int result)
            {
                string error = "SQL_DAL_EXCEPTION";
                try
                {
    
                    if (error == "SQL_DAL_EXCEPTION")
                    { 
                        throw new SQLDALException("SQL Store Procedure Error") ;
                    }
                    if (error == "DATA_ACCESS_LAYER")
                    {
                        throw new DataAccesLayerException("Data Not Found Error");
                    }
                    if (error == "CRITICAL EXCEPTION")
                    {
                        throw new CriticalException();
                    }
                }
                catch(Exception ex)
                {
                    ProcessDataAccessLayerException(ex);
                }
                return result;
            }       
        }
    }

    Project.Practice.MVP.Presenter

    BasePresenter.cs

    namespace Project.Practice.MVP.Presenter
    {
        public class BasePresenter
        {
            public IServicesProvider m_Service = null;
            public BasePresenter()
            {
                m_Service = new Services.ServicesProvider();
            }
          
            public void ProcessPresenterLayerException(Exception ex)
            {
                bool reThrow = false;
                if (ex.GetType().Equals(typeof(CriticalException)))
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else if (ex.GetType().Equals(typeof(ViewLayerException)))
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else if (ex.GetType().Equals(typeof(DataAccesLayerException)) == true)
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else if (ex.GetType().Equals(typeof(SQLDALException)) == true)
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Propogate Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
                else
                {
                    reThrow = ExceptionPolicy.HandleException(ex, "Presenter Layer Policy");
                    if (reThrow)
                    {
                        throw ex;
                    }
                }
            } 
    
        }
    } 

    CalculationPresenter.cs

    namespace Project.Practice.MVP.Presenter
    {
        public class CalculationPresenter : BasePresenter
        {
            #region Public Members
            private ICalculationView m_View = null;
            #endregion
    
            #region Public Constructor
            public CalculationPresenter(ICalculationView view)
                : base()
            {
                m_View = view;
            }
            #endregion
    
          
            public void Initialize()
            {
                //Security Check
                //If(user session expires Or login user fails
                //Throw New CriticalLayerException()
            }
            public void AddNumbers()
            {
                try
                {
                    m_View.Result= Convert.ToString(AddOperations());
                }
                catch (Exception ex)
                {
                    ProcessPresenterLayerException(ex);
                }
            }
            private int AddOperations()
            {
                int result = m_View.Numbers1 + m_View.Numbers2;
                return m_Service.AddOperation(result);
            }
        }
    } 

    Project.Practice.MVP.Web

    public partial class Calculation : CustomPage,ICalculationView
    {
        #region Private Members
        private CalculationPresenter m_Presenter = null;
        #endregion
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                m_Presenter = new CalculationPresenter((ICalculationView)this);
                if (ViewState["USER_KEY_VALUE"] == null)
                {
                    throw new ViewLayerException("Code Behind Exception");
                }
            }
            catch (Exception ex)
            {
                if (ExceptionHandleProvider.HandleException(ex, "Global Policy") == true)
                {
                    throw ex;
                }
            }       
        }
    
        #region ICalculationView Members
    
        public int Numbers1
        {
            get
            {
                return Convert.ToInt32(txtNumber1.Text);
            }
        }
    
        public int Numbers2
        {
            get
            {
                return Convert.ToInt32(txtNumber2.Text);
            }
        }
    
        public string Result
        {
            set
            {
                lblResult.Text = value;
            }
        }
    
        #endregion
        protected void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                m_Presenter.AddNumbers();
            }
            catch (Exception ex)
            {
                if (ExceptionHandleProvider.HandleException(ex, "Global Policy") == true)
                {
                    throw ex;
                }
            }      
    
        }
    
        public override string Error
        {
            set {pnlError.Visible = true;
                lblException.Text = value; ; }
        }
    }
    

    Final Show

    This exception is thrown or raised from Codebehind of aspx page.

    Configuration

    protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                m_Presenter = new CalculationPresenter((ICalculationView)this);
                if (ViewState["USER_KEY_VALUE"] == null)
                {
                    throw new ViewLayerException("Code Behind Exception");
                }
            }
            catch (Exception ex)
            {
                if (ExceptionHandleProvider.HandleException(ex, "Global Policy") == true)
                {
                    throw ex;
                }
            }       
        }
    

    Configuration

    This exception is raised from dataAccess layer.Just change error variable to test this layer.

    string error = "DATA_ACCESS_LAYER";
                try
                {
                    if (error == "SQL_DAL_EXCEPTION")
                    { 
                        throw new SQLDALException("SQL Store Procedure Not Found") ;
                    }
                    if (error == "DATA_ACCESS_LAYER")
                    {
                        throw new DataAccesLayerException("Data Not Found Error");
                    }
                    if (error == "CRITICAL EXCEPTION")
                    {
                        throw new CriticalException();
                    }
                }

    Configuration

    This business layer exception and it is occurred in Presenter layer. Just enter the value as given in the screenshot.

    public void AddNumbers()
           {
               try
               {
                   m_View.Result= Convert.ToString(AddOperations());
               }
               catch (Exception ex)
               {
                   ProcessPresenterLayerException(ex);
               }
           }
    

    This how one can create the custom exception as per the requirement.The demo project requires enterprise library dlls ,so one needs to install the Microsoft Enterprise library to run this source code given.

    I tried my best to put the sufficient information to explain the working model of custom Exception using Enterprise Library.

    Reference

    Built Exception Handling Block Using UI InterfaceEnterprise Library ExceptionHandling Block

    Model View PresenterMVP Architecture

    Conclusion

    Any correction, criticism and advise are most welcome.

    License

    This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

    Share

    About the Author

    santosh poojari
    Technical Lead
    India India
    Whatsup-->Exploring--> MVC/HTML5/Javascript & Virtualization.......!
    www.santoshpoojari.blogspot.com

    You may also be interested in...

    Pro
    Pro

    Comments and Discussions


    Discussions posted for the Published version of this article. Posting a message here will take you to the publicly available article in order to continue your conversation in public.
     
    Questionhow to run it in visual studio 2010 with .net 4 Pin
    Anusha N Rao3-Aug-11 23:34
    memberAnusha N Rao3-Aug-11 23:34 
    AnswerRe: how to run it in visual studio 2010 with .net 4 Pin
    santosh poojari3-Aug-11 23:57
    membersantosh poojari3-Aug-11 23:57 
    GeneralRe: how to run it in visual studio 2010 with .net 4 Pin
    Anusha N Rao4-Aug-11 0:15
    memberAnusha N Rao4-Aug-11 0:15 
    GeneralMy vote of 1 Pin
    zdlik29-Nov-09 16:57
    memberzdlik29-Nov-09 16:57 
    GeneralMy vote of 1 Pin
    zdlik29-Nov-09 16:55
    memberzdlik29-Nov-09 16:55 
    GeneralMy vote of 1 Pin
    zdlik29-Nov-09 16:45
    memberzdlik29-Nov-09 16:45 
    GeneralGood job Pin
    ray_ronnared7-Jul-09 4:09
    memberray_ronnared7-Jul-09 4:09 
    GeneralRe: Good job Pin
    santosh poojari27-Jul-09 2:28
    membersantosh poojari27-Jul-09 2:28 
    GeneralGreat Post Pin
    phamhoang2-Feb-09 21:55
    memberphamhoang2-Feb-09 21:55 
    GeneralRe: Great Post Pin
    santosh poojari10-Feb-09 19:38
    membersantosh poojari10-Feb-09 19:38 
    GeneralRe: Great Post Pin
    chucucon8-May-09 6:27
    memberchucucon8-May-09 6:27 

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

    Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

    | Advertise | Privacy | Terms of Use | Mobile
    Web02 | 2.8.160927.1 | Last Updated 30 Oct 2008
    Article Copyright 2008 by santosh poojari
    Everything else Copyright © CodeProject, 1999-2016
    Layout: fixed | fluid