轉帖|其它|編輯:郝浩|2010-11-26 14:25:01.000|閱讀 559 次
概述:在實際開發中,常常有這樣的需求,即頁面是由多個相對獨立的控件組成,其中一個控件的錯誤不能影響到其它控件的正常顯示。這就需要在控件內部捕捉錯誤,并自行處理錯誤,然而控件基類并沒有提供這樣的錯誤捕捉功能。如何用簡單有效方法來實現呢?本文將介紹Web控件的異常處理方法,希望對大家有幫助。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在使用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}
上面的代碼只重載了OnPreRender、Render和CreateChildControls三個方法,實際上還有OnInit、OnLoad等,可以視實際需要而重載,這樣重載之后,所有錯誤都被捕捉,并存放在錯誤棧中,并在呈現時將錯誤以某種格式呈現在界面上。注意,繼承AbstractControl基類的控件應重載如RenderByCatchedException之類的方法。
如果某些錯誤不希望被捕捉,而是直接拋出到頁面上,這時候還可以調用Interrupt方法來將錯誤直接拋出到頁面上,并中斷整個頁面的執行。
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自:博客轉載