在使用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方法来将错误直接抛出到页面上,并中断整个页面的执行。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索异常
, 控件
, exception
, 错误
, protected
, 处理
Web异常处理页面
webapi 异常处理、webservice异常处理、java web 异常处理、java web项目异常处理、webmagic 异常处理,以便于您获取更多的相关知识。