程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> 探討對Web控件的異常處理

探討對Web控件的異常處理

編輯:關於ASP.NET

在使用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    {
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方法來將錯誤直接拋出到頁面上,並中斷整個頁面的執行。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved