ASP.NET AJAX入门系列(8):自定义异常处理

UpdatePanel控件异步更新时,如果有错误发生,默认情况下会弹出一个Alert对话框显示出错误信息,这对用户来说是不友好的,本文看一下如何在服务端和客户端脚本中自定义异常处理,翻译自官方文档。

 

主要内容

1.在服务端自定义异常处理

2.在客户端脚本中自定义异常处理

 

一.在服务端自定义异常处理

1.添加ASPX页面并切换到设计视图。

2.在工具箱中AJAX Extensions标签下双击ScriptManagerUpdatePanel控件添加到页面中。

3.在UpdatePanel控件中添加两个TextBox,一个Label,一个Button和一些文字,并设置ButtonText属性值为“Calculate”。

4.双击Calculate按钮并添加如下代码到事件处理中。

protected void Button1_Click(object sender, EventArgs e)
{
    
try
    
{
        
int a = Int32.Parse(TextBox1.Text);

        
int b = Int32.Parse(TextBox2.Text);

        
int res = a / b;

        Label1.Text 
= res.ToString();
    }


    
catch (Exception ex)
    
{
        
if (TextBox1.Text.Length > 0 && TextBox2.Text.Length > 0)
        
{
            ex.Data[
"ExtraInfo"= " You can't divide " +

                TextBox1.Text 
+ " by " + TextBox2.Text + ".";

        }

        
throw ex;
    }

}

在事件处理代码中包含了一个try-catch语句块,在try中进行除法运算,如果运算失败,在catch中设置ExtraInfo信息并重新抛出异常。

5.切换到设计视图并选择ScriptManager控件。

6.在属性窗口中的工具栏中,选择事件按钮,并双击AsyncPostBackError

7.添加如下代码到AsyncPostBackError事件处理。

protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e)
{
    
if (e.Exception.Data["ExtraInfo"!= null)
    
{
        ScriptManager1. AsyncPostBackErrorMessage 
=

            e.Exception.Message 
+

            e.Exception.Data[
"ExtraInfo"].ToString();

    }

    
else
    
{       ScriptManager1.AsyncPostBackErrorMessage =

            
"An unspecified error occurred.";
    }

}

检测异常的ExtraInfo是否为空,并设置为ScriptManager控件的AsyncPostBackErrorMessage,如果不设置则会创建一个默认的异常。

8.保存并按Ctrl + F5运行。

9.在每一个文本框中输入大于零的数,并单击Calculate按钮提交成功。

10.在第二个文本框中输入0,单击Calculate将会引发一个异常。浏览器将会显示一个对话框,提示的信息为我们在服务端设置的信息。

二.在客户端脚本中自定义异常处理

前面的异常处理是在服务端通过设置ScriptManager控件的属性来进行处理,下面将看一下如何在客户端脚本中使用PageRequestManager类来进行异常处理,并用<div>元素来代替浏览器默认的Alert对话框。

1.在我们前面创建的页面中,切换到代码视图。

2.添加如下的HTML元素到页面中(官方文档中有点错误)

<div id="AlertDiv" language="javascript" onclick="return AlertDiv_onclick()">

    
<div id="AlertMessage">

    
</div>

    
<br />

    
<div id="AlertButtons">

        
<input id="OKButton" type="button" value="OK" runat="server" onclick="ClearErrorState()" />

    
</div>

</div>

3.在HEAD元素中添加如下样式标记。

<style type="text/css">

    #UpdatePanel1 
{

      width
: 200px; height: 50px;

      border
: solid 1px gray;

    
}


    #AlertDiv
{

    left
: 40%; top: 40%;

    position
: absolute; width: 200px;

    padding
: 12px; 

    border
: #000000 1px solid;

    background-color
: white; 

    text-align
: left;

    visibility
: hidden;

    z-index
: 99;

    
}


    #AlertButtons
{

    position
: absolute; right: 5%; bottom: 5%;

    
}


</style>

4.切换到设计视图并确保你的页面如下所示。

5.在属性窗口中的下拉列表中选择DOCUMENT元素(它对应的是页面<Body>元素),设置Id属性值为bodytag

6.切换到代码视图。

7.添加如下<script>代码块。

<script type="text/javascript" language="javascript">

var divElem = 'AlertDiv';

var messageElem = 'AlertMessage';

var bodyTag = 'bodytag';

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);

function ToggleAlertDiv(visString)

{

     
if (visString == 'hidden')

     
{

         $get(bodyTag).style.backgroundColor 
= 'white';                         

     }


     
else

     
{

         $get(bodyTag).style.backgroundColor 
= 'gray';                         

 

     }


     
var adiv = $get(divElem);

     adiv.style.visibility 
= visString;

 

}


function ClearErrorState() {

     $get(messageElem).innerHTML 
= '';

     ToggleAlertDiv('hidden');                     

}


function EndRequestHandler(sender, args)

{

   
if (args.get_error() != undefined)

   
{

       
var errorMessage;

       
if (args.get_response().get_statusCode() == '200')

       
{

           errorMessage 
= args.get_error().message;

       }


       
else

       
{

           
// Error occurred somewhere other than the server page.

           errorMessage 
= 'An unspecified error occurred. ';

       }


       args.set_errorHandled(
true);

       ToggleAlertDiv('visible');

       $get(messageElem).innerHTML 
= errorMessage;

   }


}


</script>

在代码块中,主要做以下几件事:

1)定义PageRequestManager类的endRequest事件处理,在事件处理中,当有错误发生时将显示AlertDiv

2)定义ToggleAlertDiv函数,当有错误发生时它用来显示或者隐藏AlertDiv元素,并且改变页面的背景颜色。

3)定义ClearErrorState函数,它用来隐藏错误信息的UI

8.保存并按Ctrl + F5运行。

9.在每一个文本框中输入大于零的数,并单击Calculate按钮提交成功。

10.在第二个文本框中输入0,单击Calculate将会引发一个异常。这时自定义的AlertDiv将会显示出来代替了默认的Alert对话框,如下图所示:

[翻译自官方文档]

作者:TerryLee
出处:http://terrylee.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
posted @ 2006-11-13 16:58 TerryLee 阅读(8550) 评论(44)  编辑 收藏 所属分类: ASP.NETAJAX

  回复  引用    
#1楼 2006-11-14 10:39 | charming[匿名] [未注册用户]
:)
  回复  引用  查看    
#2楼 2006-11-15 17:01 | Kevin Wu      
好,又出新的了,继续努力,继续关注,多谢共享 :)
  回复  引用  查看    
#3楼 [楼主]2006-11-15 20:04 | TerryLee      
@Kevin Wu
:)
  回复  引用    
#4楼 2006-11-16 16:29 | AJAX入门 [未注册用户]
老大是不是三少了段代码阿,跑不起来啊。
<div id="AlertDiv" language="javascript" onclick="return AlertDiv_onclick()"> 这个函数在哪里啊?

  回复  引用    
#5楼 2006-11-17 15:21 | guest [未注册用户]
不行呀
  回复  引用  查看    
#6楼 2006-11-17 22:00 | 陈招展      
跑不起来啊!还是弹出服务端的异常处理

  回复  引用  查看    
#7楼 [楼主]2006-11-18 18:00 | TerryLee      
@陈招展
翻译自官方文档
可以参考一下:
http://ajax.asp.net
  回复  引用  查看    
#8楼 2006-11-20 15:18 | ColdDog      
这个例子是有错的,TerryLee人呢?:)
  回复  引用    
#9楼 2006-11-21 16:23 | 天堂有路你不走 [未注册用户]
把那个onclick事件去掉就行了吧,也没什么用
  回复  引用    
#11楼 2006-12-14 11:14 | Batista [未注册用户]
可以跑啊?没问题
  回复  引用  查看    
#12楼 2006-12-20 15:43 | Anthan      
如果是在客户端脚本中自定义异常处理的话还需要ScriptManager1_AsyncPostBackError这个里面的那些处理吗?
另外,我这边死活就是显示不出来自定义的那个Alert窗口,只是显示一行文字,IDE中Design下都显示不了。
并且显示的还是服务器端的异常处理
  回复  引用  查看    
#13楼 [楼主]2006-12-23 16:38 | TerryLee      
@Anthan
需要啊,就是在那个方法里面捕获到异常,对异常进行处理

你用的是哪个版本呢?
  回复  引用  查看    
#14楼 2006-12-24 17:07 | 丹心猪(Dansinge)      
把onclick="return AlertDiv_onclick()"
改成onclick="return ToggleAlertDiv('hidden')"
就OK了
  回复  引用    
#15楼 2006-12-24 17:19 | qqwwee [未注册用户]
例子没问题的,要把

<script> 脚本放在ScriptManager 控件后面,否则就会是javascript的那个alert

花了不少时间研究这个,脚本不能放在</head>前,不爽啊
  回复  引用  查看    
#16楼 2007-02-24 09:55 | 若寒      
@qqwwee
谢谢!!终于OK了.
在IE7中要加上:
var abutton = $get('OKButton');
adiv.style.visibility = visString;
不然那个OKButton一直都会显示.
  回复  引用    
#17楼 2007-03-23 16:14 | 扑街仔 [未注册用户]
就是想不明白为什么script一定要放在ScriptManager 后面例子才成功..
能解释一下吗??
  回复  引用    
#18楼 2007-03-29 19:52 | JAMES [未注册用户]
在第一个例子中是有错的!throw ex;
改成 Label1.Text =("你输入有错");
  回复  引用    
#19楼 2007-04-04 17:03 | RongJun [未注册用户]
var adiv = $get(divElem);
adiv.style.visibility = visString;
请问这两具是干什么的啊 ?????????????

我看了一下代码,我的理解就是控制 <div id="AlertMessage">的是否显示
所以我把上面的那两句代码换成了
document.getElementById("AlertMessage").style.visibility=visString
但是就没有错误信息显示了...
那就是说我的想法是错的啦??

那这两句到底起到上面作用啊,,请指点



  回复  引用    
#20楼 2007-04-04 17:13 | RongJun [未注册用户]
不好意思,刚刚仔细又看了一下,原来我想的是对的,只是名字弄错了
不是:
document.getElementById("AlertMessage").style.visibility=visString
而是:
document.getElementById("AlertDiv").style.visibility=visString

呵呵!!!!!!!!!!!!!

很喜欢TerryLee的文章,要是TerryLee能写写NHibernate从入门到精通的系列就好了,呵呵!!!!!!!!!!!!!!!!


  回复  引用    
#21楼 2007-05-28 15:29 | 总结一下 [未注册用户]
综合给为老兄的错误解决方法,终于调试成功了,这里总结一下:
1,在<body>加上 id="bodytag"
2,把onclick="return AlertDiv_onclick()"
改成onclick="return ToggleAlertDiv('hidden')"
3,把script放在ScriptManager后面。
  回复  引用    
#22楼 2007-07-03 17:52 | yyc [未注册用户]
alert还是弹出了,先弹出alert,然后显示了那个隐藏的div,如果让它不弹出alert?
  回复  引用    
#23楼 2007-07-03 17:55 | yyc [未注册用户]
不好意思搞错了,是我自己写了alert,呵呵
  回复  引用    
#24楼 2007-07-04 09:39 | qingyun163 [未注册用户]
@qqwwee
兄弟,大家对js不是很了解啊,当然可以放在<head>区了,看我的:

<title>使用客户端脚本对UpdateProgress编程</title>
<style type="text/css">
#UpdatePanel1{width:200px; height:100px;border: 1px solid gray;}
#UpdateProgress1{width:200px; background-color: #FFC080;bottom: 0%; left: 0px; position: absolute;}
</style>
<script type="text/javascript">
var prm,postBackElement;
window.onload = function(){
prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndReuqest);
}

function InitializeRequest(sender,args){
if(prm.get_isInAsyncPostBack()){
args.set_cancel(true);
}

postBackElement = args.get_postBackElement();

if(postBackElement.id == "Panel1Trigger"){
document.getElementById("UpdateProgress1").style.display = "block";
}
}

function EndReuqest(sender,args){
if(postBackElement.id == "Panel1Trigger"){
document.getElementById("UpdateProgress1").style.display = "none";
}
}

function CancelAsyncPostBack(){
if(prm.get_isInAsyncPostBack())
prm.abortPostBack();
}
</script>
</head>

一个错误也没有...
  回复  引用    
#25楼 2007-07-04 09:49 | qingyun163 [未注册用户]
<title>自定义异常处理</title>
<style type="text/css">
#UpdatePanel1{width: 200px; height: 50px;border: solid 1px gray;}
#AlertDiv{left: 40%; top: 40%;position: absolute; width: 200px;padding: 12px; border: #000000 1px solid;background-color: white; text-align: left;visibility: hidden;z-index: 99;}
#AlertButtons{position: absolute; right: 5%; bottom: 5%;}
</style>
<script type="text/javascript">
window.onload = function(){
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler);
}

function EndRequestHandler(sender,args){
if(args.get_error() != 'undefind'){
var errorMessage;
if(args.get_response().get_statusCode() == "200"){
errorMessage = args.get_error().message;
}else{
errorMessage = "An unspecified error occurred.";
}

args.set_errorHandled(true);
ToggleAlertDiv('visible');
document.getElementById("AlertMessage").innerHTML = errorMessage;
}
}

function ToggleAlertDiv(visString){
if(visString == "hidden")
document.body.style.backgroundColor = "";
else
document.body.style.backgroundColor = "gray";

document.getElementById("AlertDiv").style.visibility = visString;
}

function ClearErrorState(){
document.getElementById("AlertMessage").innerHTML = '';
ToggleAlertDiv('hidden');
}
</script>
  回复  引用    
#26楼 2008-02-25 14:16 | 顺z [未注册用户]
因为把Script放在HEAD里面导致Sys错误。。。把它放在ScriptManager后面就没错误了。。。
  回复  引用    
#27楼 2008-02-29 11:14 | liaobing [未注册用户]
我跟12楼的情况一样的,以前从来没有接触过ajax的异常处理,现在正处在学习阶段,Terrylee的文章很好
我不知道该怎么调试才能显示出来,我现在弹出来的还是服务器端的异常处理啊,客户端的那个提示框根本就没有出来,希望指点一下。
  回复  引用    
#28楼 2008-06-30 22:12 | veinyf#163.com [未注册用户]
--引用--------------------------------------------------
liaobing: 我跟12楼的情况一样的,以前从来没有接触过ajax的异常处理,现在正处在学习阶段,Terrylee的文章很好
我不知道该怎么调试才能显示出来,我现在弹出来的还是服务器端的异常处理啊,客户端的那个提示框根本就没有出来,希望指点一下。
--------------------------------------------------------


证明客户端没“拦截住”服务端代码
客户端代码没有起作用~1
  回复  引用    
#29楼 2008-07-01 16:21 | 着急的人 [未注册用户]
throw ex.处怎么老报异常啊。
就是抛步出来啊。是怎么回事啊

  回复  引用  查看    
#30楼 2008-08-13 01:48 | thomaschen      
--引用--------------------------------------------------
着急的人: throw ex.处怎么老报异常啊。
<br>就是抛步出来啊。是怎么回事啊
<br>
--------------------------------------------------------
我也一样 我想最可能是版本问题吧
我是刚刚安装的 asp.net 2.0 ajax
  回复  引用  查看    
#31楼 2008-08-13 11:05 | thomaschen      
楼主 请问下 里面用多了一些js语法应该是asp.net ajajx独有的
这个语法在哪里可以获取呢
比如args.set_errorHandled(true);

除了你应用的这些外有没有其他的语法、功能的?
  回复  引用  查看    
#32楼 [楼主]2008-08-13 21:38 | TerryLee      
@thomaschen
这不是什么语法吧,只是一个函数而已。

具体的你可以查看相关的SDK