
3.7 Async-Postback的错误控管
当Async-Postback的要求到达Server时,若处理期间发生任何的异常,ScriptManager控件会触发AsyncPostbackError事件,如果设计师未挂载任何事件的话,ScriptManager控件便会输出AsyncPostbackErrorMessage属性所设定的信息,此时浏览器便会以信息窗方式显示此错误信息,若AsyncPostbackErrorMessage属性值为空白,ScriptManager控件会直接输出异常的错误信息。我承认,这段说明对读者来说有些模糊,文教不如身教,请照以下的步骤来创建一个网页。
1. 创建一个新网页,命名为ErrorCatchs.aspx。
2. 在页面中放入一个ScriptManager控件。
3. 在页面中放入一个UpdatePanel控件。
4. 将UpdatePanel1控件的UpdateMode设为Conditional。
5. 在UpdatePanel控件中放入一个Button控件,将Text属性设为Catch Me。
6. 在Button控件的Click事件中键入程序3-13的代码。
程序3-13
Samples\3\AjaxDemo1\ErrorCatchs.aspx.cs protected void Button1_Click(object sender, EventArgs e) { throw new Exception("Error in Catch Me !!"); }
完成并运行此程序,点击Button后便可看到浏览器弹出报错信息,而此报错信息便是Click事件所抛出的异常信息,如图3-11所示。

图3-11
这就是ScriptManager控件最基本的错误控管机制,当然!这对实务上来说仍嫌过于初级,应该更明确地指出此错误信息是在Async-Postback时发生的。请照以下的步骤,一步步地修改此例子。
1. 挂载事件至ScriptManager的AsyncPostbackError事件。
2. 键入程序程序3-14的代码。
程序3-14
Samples\3\AjaxDemo1\ErrorCatchs.aspx.cs protected void ScriptManager1_AsyncPostbackError(object sender, AsyncPostbackErrorEventArgs e) { ScriptManager1.AsyncPostbackErrorMessage = string.Format("异步回传错误:{0}", e.Exception.Message); }
重新运行程序后,便可看到更明显的错误信息,指出此错误是发生于异步机制,如图3-12 所示。

图3-12
这些就是AsyncPostbackErrorMessage及AsyncPostbackError事件的用法,这个显示错误的形式会受到ScriptManager的AllowCustomErrorsRedirect属性值的影响,当此值为Ture时,若web.config中明确设定了错误的页面时,ScriptManager就会在错误发生时,自动转向至该页面。请照以下的步骤修改此例子。
1. 修改web.config,加入程序3-15中粗体字部分的设定值。
2. 创建一个HTML网页,内容如程序3-16所示。
程序3-15
Samples\3\AjaxDemo1\web.config <system.web> <customErrors defaultRedirect="GenericError.htm" mode="On"/> ……………
程序3-16
Samples\3\AjaxDemo1\GenericError.htm <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <meta http-equiv="Content-Type" content="text/html; charset=big5"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> </head> <body> 处理期间发生错误!! </body> </html>
重新运行程序后,便会发现当点击Button后,错误不再以信息窗方式显示,而是自动导向GenericError.htm页面,如图3-13所示。

图3-13
当Async-Postback处理的时间过长时,Client端也会引发异常来终止此次要求,这个时间可通过ScriptManager控件的AsyncPostbackTimeOut属性来设定,单位是秒,默认值是90秒,也就是当Client端送出Async-Postback要求后等待Server响应,若超过90秒未收到Server响应,那么客户端自身就会终止此次要求。请照以下步骤修改本例。
1. 设定ScriptManager控件的AsyncPostbackTimeOut属性为20。
2. 在Button控件之Click事件键入程序3-17的程序代码。
程序3-17
Samples\3\AjaxDemo1\ErrorCatchs.aspx.cs protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(30000); }
运行程序后点击Button,等待20秒后浏览器便会显示错误信息,如图3-14所示。

图3-14
咦,先前不是已经设定错误时所导向的页面了吗?为何此处仍然以信息窗显示?别弄混了,AsyncPostbackTimeout属性所针对的是Client端的等待时间,也就是点击Button后Client端所等待响应的时间,若时间到Client端未收到Server的响应,便直接显示Timeout的信息,所以这与Server端的错误机制无关。