zoukankan      html  css  js  c++  java
  • 探讨对Web控件的异常处理

    在使用ASP.NET时,常常使用Page的错误事件Error进行错误捕捉和处理。这种方式可以集中处理所有异常,这种方式有利有弊。集中处理的好处就不用啰嗦了,这里只说明一下这种方式的局限,就是当页面中的某个控件发生异常之后,整个页面执行都会中断,然后处理异常,这样一来,页面就无法显示。

    在实际开发中,常常有这样的需求,即页面是由多个相对独立的控件组成,其中一个控件的错误不能影响到其它控件的正常显示。这就需要在控件内部捕捉错误,并自行处理错误,然而控件基类并没有提供这样的错误捕捉功能。如何用简单有效方法来实现呢?

    其实我们可以实现一个基类,并把所有在控件生命期中会调用到的方法都封装起来,这样只要继承这个控件,就可以方便地实现在控件内部自行捕捉错误的功能。请看下面的代码:

      1public abstract class AbstractControl: Control
      2{
      3    /// <summary>
      4    /// 异常栈
      5    /// </summary> 

      6    public Stack Exceptions
      7    {
      8        get
      9        {
     10            if (exceptions == null)
     11            {
     12                exceptions = new Stack();
     13            }

     14            return exceptions;
     15        }

     16    }

     17
     18    protected override void CreateChildControls()
     19    {
     20        try
     21        {
     22            CreateChildControlsByCatchedException();
     23        }

     24        catch (HttpUnhandledException)
     25        {
     26            throw;
     27        }

     28        catch (Exception ex)
     29 408_436_Open_Image.style.display='inline'; Codehighlighter1_408_436_Open_Text.style.display='inline';" src="/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>        {
     30            Exceptions.Push(ex);
     31        }

     32    }

     33
     34    /// <summary>
     35    /// 创建子控件(已进行异常捕捉处理)
     36    /// </summary>

     37    protected virtual void CreateChildControlsByCatchedException()
     38    {
     39    }

     40
     41    /// <summary>
     42    /// 
     43    /// </summary>
     44    /// <param name="e"></param>

     45    protected override void OnPreRender(EventArgs e)
     46    {
     47        try
     48        {
     49            OnPreRenderByCatchedException(e);
     50        }

     51        catch (HttpUnhandledException)
     52        {
     53            throw;
     54        }

     55        catch (Exception ex)
     56        {
     57            Exceptions.Push(ex);
     58        }

     59    }

     60
     61    /// <summary>
     62    /// 呈现前事件(已进行错误捕捉处理)
     63    /// </summary>
     64    /// <param name="e"></param>

     65    protected virtual void OnPreRenderByCatchedException(EventArgs e)
     66    {
     67        base.OnPreRender (e);
     68    }

     69    
     70    /// <summary>
     71    /// 设计时的呈现前事件
     72    /// </summary>
     73    /// <param name="e"></param>

     74    protected virtual void DesigningOnPreRenderByCatchedException(EventArgs e)
     75    {
     76    }

     77
     78    /// <summary>
     79    /// 呈现
     80    /// </summary>
     81    /// <param name="writer"></param>

     82    protected override void Render(HtmlTextWriter writer)
     83    {
     84        if (Exceptions.Count > 0)
     85        {
     86            while (Exceptions.Count > 0 )
     87            {
     88                Exception ex = (Exception) Exceptions.Pop();
     89                RenderException(writer, ex);
     90            }

     91            return;
     92        }

     93        
     94        try
     95        {
     96            RenderByCatchedException(writer);
     97        }

     98        catch (HttpUnhandledException)
     99        {
    100            throw;
    101        }

    102        catch (Exception ex)
    103        {
    104            RenderException(writer, ex);
    105        }

    106    }

    107
    108    /// <summary>
    109    /// 呈现(已进行错误捕捉处理)
    110    /// </summary>
    111    /// <param name="writer"></param>

    112    protected virtual void RenderByCatchedException(HtmlTextWriter writer)
    113    {
    114        base.Render (writer);
    115    }

    116
    117    /// <summary>
    118    /// 呈现异常
    119    /// </summary>
    120    /// <param name="writer"></param>
    121    /// <param name="ex"></param>

    122    private void RenderException(HtmlTextWriter writer, Exception ex)
    123    {         
    124        writer.AddAttribute(HtmlTextWriterAttribute.Title, BuildExceptionInfomation(ex));
    125        writer.AddStyleAttribute("font-weight""700");
    126        writer.AddStyleAttribute("color""#f00");
    127        writer.AddStyleAttribute("border""1px solid #ddd");
    128        writer.AddStyleAttribute("cursor""pointer");
    129        writer.AddStyleAttribute("padding""0px 3px 0px 3px");
    130        writer.AddStyleAttribute("background-color""#ffe");
    131        writer.RenderBeginTag(HtmlTextWriterTag.Span);
    132        writer.Write("!");
    133        writer.RenderEndTag();
    134    }

    135
    136    /// <summary>
    137    /// 生成异常信息
    138    /// </summary>
    139    /// <param name="ex"></param>
    140    /// <returns></returns>

    141    private string BuildExceptionInfomation(Exception ex)
    142    {
    143        StringBuilder sb = new StringBuilder();
    144        sb.Append(ex.Message);
    145        sb.Append(Environment.NewLine);
    146        sb.Append(ex.GetType().FullName);
    147        sb.Append(Environment.NewLine);
    148        sb.Append(ex.StackTrace);
    149        return sb.ToString();
    150    }

    151    
    152    /// <summary>
    153    /// 中断程序的执行
    154    /// </summary>
    155    /// <param name="ex"></param>

    156    protected virtual void Interrupt(Exception ex)
    157    {
    158        throw new HttpUnhandledException(ex.Message, ex);
    159    }

    160}

    161

    上面的代码只重载了OnPreRender、Render和CreateChildControls三个方法,实际上还有OnInit、OnLoad等,可以视实际需要而重载,这样重载之后,所有错误都被捕捉,并存放在错误栈中,并在呈现时将错误以某种格式呈现在界面上。注意,继承AbstractControl基类的控件应重载如RenderByCatchedException之类的方法。

    如果某些错误不希望被捕捉,而是直接抛出到页面上,这时候还可以调用Interrupt方法来将错误直接抛出到页面上,并中断整个页面的执行。

  • 相关阅读:
    739. Daily Temperatures
    556. Next Greater Element III
    1078. Occurrences After Bigram
    1053. Previous Permutation With One Swap
    565. Array Nesting
    1052. Grumpy Bookstore Owner
    1051. Height Checker
    数据库入门及SQL基本语法
    ISCSI的概念
    配置一个IP SAN 存储服务器
  • 原文地址:https://www.cnblogs.com/rrooyy/p/481419.html
Copyright © 2011-2022 走看看