Ajax与CustomErrors的尴尬
在ASP.NET程序中,为了给用户显示友好的错误信息,通常在web.config中进行如下的设置:
<customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm">
</customErrors>
但如果是一个ajax请求在服务端发生了错误,将遭遇一个尴尬。我们就遭遇过这样的尴尬,见下图:

上图中显示“抱歉!系统发生了错误!”的地方是ajax加载的内容,ajax部分的js代码如下:

$.ajax({
success: function (data) {
if (data) {
resultElement.html(data);
}
}
});

从上面的代码可以知道,虽然ajax请求出错,但依然在success回调函数中处理了,导致将定制错误信息作为正常返回内容显示出来,从而造成前图中的尴尬。
刚面对这个问题时,我们想到的解决方法是根据statusCode进行判断,如果是500,就知道是发生了错误,然后进行特定的错误处理。我们写了这样的测试代码:

$.ajax({
statusCode: {
500: function () {
console.log('error!');
}
},
success: function (data) {
if (data) {
resultElement.html(' ' + data);
}
}
});

结果发现,并没有执行对应于500 statusCode的回调函数。
在浏览器中查看了一下,原来服务器端返回的是302状态码。也就是说,在默认情况下,ASP.NET用重定向的方式向浏览器返回定制错误信息。在web.config>CustomErrors中,有个专门的属性redirectMode,其默认值就是ResponseRedirect。redirectMode还有个值是ResponseRewrite,能不能解决我们的问题呢?我们改一下web.config试一试,修改如下:
<customErrors mode="RemoteOnly" defaultRedirect="/error/error.htm" redirectMode="ResponseRewrite">
</customErrors>
结果发现,的确是返回500状态码了,但定制错误错误没了,返回的是Runtime Error。

当设置redirectMode="ResponseRewrite",发生错误时,ASP.NET实际会执行Server.Transfer()返回定制错误信息页面,而Server.Transfer()与ASP.NET MVC路由存在兼容问题,详见CustomErrors does not work when setting redirectMode=“ResponseRewrite”。
服务端暂时找不到解决方法,从浏览器端下手试试。
我们想到一个解决思路,就是根据302 statusCode进行处理,根据我们的实际场景(redirectMode是默认值ResponseRedirect),如果服务端返回的是302,肯定是发生了错误。于是,我们改为如下的ajax代码:

$.ajax({
statusCode: {
302: function () {
console.log('error!');
}
},
success: function (data) {
if (data) {
resultElement.html(' ' + data);
}
}
});

结果发现,并没有执行302的回调函数,也就是说ajax请求根本拿不到302状态码(http status code),实际得到的还是200状态码。
既然浏览器端也找不到解决方法,只有“回头是岸”,回到服务器端。
既然CustomErrors解决不了问题,那我们就把它给废了:
<customErrors mode="Off">
</customErrors>
然后自己处理定制错误信息,在Global.asax.cs中添加如下的代码:

protected void Application_Error(Object sender, EventArgs e)
{
Exception lastError = Server.GetLastError();
if (lastError != null)
{
Response.StatusCode = 500;
Response.WriteFile("~/error/error.htm");
Server.ClearError();
}
}

问题就这样解决了!
另外,不用默认的“重定向显示定制错误信息”方式还有一个很大的好处,在发生错误时,浏览器地址栏不会跳转,这样用户反馈错误时,可以直接反馈发生问题时实际访问的完整网址。截个图纪念一下CustomErrors曾经带来的烦恼。

转载自:http://www.cnblogs.com/dudu/archive/2012/11/20/ajax_custom_error.html
Ajax与CustomErrors的尴尬的更多相关文章
- 原生AJAX入门讲解(含实例)
相对于jQuery.YUI以及其他一些类库的AJAX封装,原生JS的AJAX显得那么的尴尬,兼容性不好,要记很多的方法属性,调用不便捷,代码臃肿...但我还是想说,原生JS才是最根本最底层的知识(虽然 ...
- 学习笔记之MVC级联及Ajax操作
由于刚转型到MVC,MVC的架构模式很多不是很清楚,比如今天就想做个级联的操作,因为之前的ASP.NET的方式是通过:控件-->添加事件-->后台编写级联事件进行触发,但是这个MVC就不同 ...
- Ajax工作原理
在写这篇文章之前,曾经写过一篇关于AJAX技术的随笔,不过涉及到的方面很窄,对AJAX技术的背景.原理.优缺点等各个方面都很少涉及null.这次写这篇文章的背景是因为公司需要对内部程序员做一个培训.项 ...
- ajax post提交form表单 报400错误 解决方法
昨天晚上做项目遇到了一个奇怪的问题,我用ajax提交一个form表单,后台Java方法用的是一个实体接,但是他根本不进方法体中,直接给我一个400的错误,一开始我以为是我路径的问题(尴尬),结果直接访 ...
- 关于Ajax工作原理
1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax ...
- Ajax技术
1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax ...
- Ajax工作原理(转)
1.ajax技术的背景 不可否认,ajax技术的流行得益于google的大力推广,正是由于google earth.google suggest以及gmail等对ajax技术的广泛应用,催生了ajax ...
- ajax浅析---ScriptManager
使用ScriptManager控件 它用来处理页面上的所有组件以及页面局部更新,生成相关的客户端代理脚本以便能够在JavaScript中访问Web Service,所有需要支持ASP.NET AJAX ...
- jquery ajax跨域访问webservice配置
1.webservice方法 [System.Web.Script.Services.ScriptService] public class TestService : System.Web.Serv ...
随机推荐
- LaTeX新人30分钟从完全陌生到基本入门
From:http://www.360doc.com/content/13/0117/11/2886802_260681908.shtml 对于真心渴望迅速上手LaTeX的人,前言部分可以跳过不看. ...
- oracle实例,数据库,服务器区别
实例(instance) 实例是一个非固定的,基于内存的基本进程与内存结构.当服务器关闭时,实例就不存在了. 数据库(DataBase) 数据库指固定的,基于磁盘的数据文件,控制文件,日志文件,参数文 ...
- MVC应用程序显示上传的图片
MVC应用程序显示上传的图片 前两篇<MVC应用程序实现上传文件>http://www.cnblogs.com/insus/p/3590907.html和<MVC应用程序实现上传文件 ...
- NET 类库
NET 类库研究必备参考 扣丁格鲁 .NET 类库的强大让我们很轻松的解决常见问题,作为一个好专研的程序员,为了更上一层楼,研究CLR的基础类库实现是快速稳定的捷径. 一般场景下,采用 Reflect ...
- 第一章 CLR 的执行模型
CLR via C# 读书笔记:第一章 CLR 的执行模型(1) 第Ⅰ部分CLR基础.这部分为三章(第一章:CLR的只想能够模型,第二章:生成.打包.部署和管理应用程序及类型,第三章:共享程序集和强命 ...
- SQLSERVER清空(Truncate)被外键引用的数据表
前言:我们知道SQLSERVER清空数据表有两种方式Delete和Truncate,当然两者的不同大家也都知道(不清楚的可以MSDN).不过这个错误“Cannot truncate table be ...
- WebForm页面生命周期WEBFORM_ASPNET控件树的生成和作用
WebForm页面生命周期WEBFORM_ASPNET控件树的生成和作用 摘要 页面类是如何结合后台文件类生成整个页面的HTML的代码和后台输出的代码输出到浏览器中呢?这就牵扯到Asp.net页面生命 ...
- SQL2008R2 无法读取此系统上以前注册的服务器的列表--网上方法不可行
C:\Users\<username>\AppData\Local\Temp,然后创建两个命名为1和2的文件夹
- SOCKET网络编程细节问题1
SOCKET网络编程快速上手(二)——细节问题(1) 三.细节问题一个也不能少 Socket编程说简单也简单,程序很容易就能跑起来,说麻烦还真是麻烦,程序动不动就出问题.记得刚开始写网络代码的时候,那 ...
- 基于“泵”的TCP通讯(接上篇)
基于“泵”的TCP通讯(接上篇) 上一篇博客中说了基于“泵”的UDP通讯,附上了一个Demo,模拟飞鸽传书的功能,功能不太完善,主要是为了说明“泵”在编程中的应用.本篇文章我再附上一个关于TCP通讯的 ...