问题描述:

  在上一篇博文 “.net自定义错误页面实现” 中已经介绍了在.net中如何实现自定义错误页面实现(有需要者可以去上一篇博文了解),单纯按照上一篇博文那样设置,能够实现所有请求的异常自定义跳转,但是这样又会产生一个问题:当通过ajax提交请求获取接口提交请求,如果出现未处理的异常也会被重定向到自定义错误页面。

  针对ajax请求或者接口请求,这样返回一个重定向页面,用户体验显然不是太友好,针对这个问题,下面简单总结一下我自己的想法和解决方案,当然不一定科学和合理,所以也希望有大牛多多指点。

  解决思路,我想到的有二:
解决方案一:
  从物理结构上分割,将web项目严格分割成两个项目(当然可根据需要继续细分):网站(只有网站页面资源等内容)、接口(包括网站的所有数据逻辑处理,页面的数据请求交互都是直接同接口交互(js技术)),
  只是网站项目按照上一篇博文方式设置自定义错误页面方式,这样是能够解决问题,项目也会更加的清晰,也有很多公司的项目就是按照这种方式(尤其是webApp),
  但是在实际项目中,很多项目是没有达到这种严格区分的,所以下面的解决方案二,将介绍一个更通用的方式

解决方法二:

  解决思路是:将上一篇博文 .net自定义错误页面实现 与 上上一篇博文 .net捕捉全局未处理异常的3种方式 结合使用,并在实际开发中严格约定(出了url地址请求以外的其他请求都通过post请求实现交互),在扑捉到异常时,如果是post请求,处理异常,并清除异常。具体以步骤如下:
  第一步:定义一个请求处理结果数据MODEL,代码如下:
  

    /// <summary>
/// 请求结果MRequestResult
/// </summary>
public class MRequestResult
{
/// <summary>
/// 请求结果编码(是一个枚举值)
/// </summary>
private RequestResultCodeEnum requestResultCode; /// <summary>
/// 处理结果具体的返回值
/// </summary>
private object resultValue; /// <summary>
/// 请求结果编码(是一个枚举值)
/// </summary>
public RequestResultCodeEnum RequestResultCode
{
get
{
return this.requestResultCode;
} set
{
this.requestResultCode = value;
}
} /// <summary>
/// 处理结果具体的返回值
/// </summary>
public object ResultValue
{
get
{
return this.resultValue;
} set
{
this.resultValue = value;
}
}
} /// <summary>
/// 请求结果编码枚举值()
/// </summary>
public enum RequestResultCodeEnum
{
/// <summary>
/// 请求成功
/// </summary>
Success = , /// <summary>
/// 请求失败
/// </summary>
Fail = -,
}

第二步:按照 上一篇博文: .net自定义错误页面实现的步骤,配置好自定义错误页面相关配置操作

第三步:按照 上上一篇博文:.net捕捉全局未处理异常的3种方式 的步骤实现全局异常为处理相关操作设置

第四步:在扑捉全局未处理的异常中,添加上针对post请求的异常处理过滤(直接输入封装后的),具体代码如下:

  /// <summary>
/// 异常处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void context_Error(object sender, EventArgs e)
{
//此处处理异常
HttpContext ctx = HttpContext.Current;
HttpResponse response = ctx.Response;
HttpRequest request = ctx.Request; //获取到HttpUnhandledException异常,这个异常包含一个实际出现的异常
Exception ex = ctx.Server.GetLastError();
//实际发生的异常
Exception iex = ex.InnerException; //// 异常日志落地
//// 异常日志落地包括:记录异常文本文件日志、或者记录异常日志数据库等等(根据实际项目需要做记录) //// 获取请求方法
string httpMethod = request.HttpMethod;
//// 如果是POST请求,那么是以下请求之一
//// ajax接口请求
//// form表单提交
//// 这种情况的异常,不用跳转至自已的异常错误页面,直接返回对应系统异常
if (httpMethod.ToUpper() == "POST")
{
//// 构建返回对象值
MRequestResult requestResultM = new MRequestResult();
requestResultM.RequestResultCode = RequestResultCodeEnum.Fail;
requestResultM.ResultValue = "系统异常,请联系管理员!"; response.Write(JsonConvert.SerializeObject(requestResultM, Formatting.Indented));
ctx.Server.ClearError();//处理完及时清理异常
}
}

代码实例:

ajax请求方法及其逻辑处理实例代码:

    $(function () {
$.ajax({
async: true,
type: "post",
url: "../ActionTestResult/ContentResultTest",
data: "name=xu",
success: function (resultValue) { if (resultValue) {
//// 解析处理结果
var resultObj = $.parseJSON(resultValue); //// 当RequestResultCode==1 说明该请求成功
////(备注:并不代表处理成功,具体是否处理成功需要通过ResultValue的值根据接口约定解析做相应的逻辑处理)
if (resultObj["RequestResultCode"] == ) {
//// 自定义请求成功逻辑处理
//// 通过解析具体的ResultValue的值做相应的逻辑处理.....
if (resultObj["ResultValue"]) {
var doResult = resultObj["ResultValue"].split('^');
if (doResult && doResult.length > ) {
if (doResult[] == ) {
//// 说明处理成功,做相应的逻辑处理
alert("处理成功!");
} else {
//// 处理失败
alert(doResult[]);
} } else {
alert("操作失败!");
} } else {
alert("未知结果");
} } else {
//// 说明请求异常
//// 自定义逻辑处理
alert(resultObj["ResultValue"]);
}
} else {
//// 自定义逻辑处理
alert("操作失败!");
} console.log(resultValue);
},
error: function (data) {
//// 自定义逻辑处理
alert("系统异常,请联系管理员。电话:8888888");
console.log(data);
}
});
});

ajax对应的后台请求接受实例代码:

        /// <summary>
/// 测试
/// </summary>
/// <returns></returns>
public ContentResult ContentResultTest(string name)
{
//// 构建请求处理结果Model
MRequestResult requestResultM = new MRequestResult() { RequestResultCode = RequestResultCodeEnum.Success }; //// 业务处理结果
string doResult = string.Empty; //// 本次自作简单的参数非空判断,只一个示例
//// 处理结果本例中也只是通过^链接表示,在实际处理过程中,可以将结果通过一个Json字符串
if (string.IsNullOrEmpty(name))
{
doResult = "-1^操作失败:名称不能为空!";
}
else
{
///// 其他自定义业务逻辑处理,此处省略.....
doResult = "1^操作成功";
} requestResultM.ResultValue = doResult; //// 返回结果
return Content(JsonConvert.SerializeObject(requestResultM, Formatting.Indented)); }

是不是觉得说的有点绕,本人表述能力有限,不懂的评论交流。
最后:个人能力有限也许该解决方式并不友好,有更好的解决方法,也欢迎留言交流,多多指点,多多指教

.net自定义错误页面实现升级篇的更多相关文章

  1. C#不用union,而是有更好的方式实现 .net自定义错误页面实现 .net自定义错误页面实现升级篇 .net捕捉全局未处理异常的3种方式 一款很不错的FLASH时种插件 关于c#中委托使用小结 WEB网站常见受攻击方式及解决办法 判断URL是否存在 提升高并发量服务器性能解决思路

    C#不用union,而是有更好的方式实现   用过C/C++的人都知道有个union,特别好用,似乎char数组到short,int,float等的转换无所不能,也确实是能,并且用起来十分方便.那C# ...

  2. ASP.NET Core中显示自定义错误页面-增强版

    之前的博文 ASP.NET Core中显示自定义错误页面 中的方法是在项目中硬编码实现的,当有多个项目时,就会造成不同项目之间的重复代码,不可取. 在这篇博文中改用middleware实现,并且放在独 ...

  3. ASP.NET网站中设置404自定义错误页面

    在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页面,然后在Global.asax文件中,加入如下代码: &l ...

  4. 自定义错误页面mvc用法

    原谅我这个新手,对大神们来说这么简单的问题,竟折腾了我一个上午,仅此文章做个记录,供以后备用. 自定义错误页面(custom error pages)在asp.net webform里的配置请看htt ...

  5. 新西兰程序员 ASP.NET网站中设置404自定义错误页面

    新西兰程序员 ASP.NET网站中设置404自定义错误页面 在用ASP.NET WebForm开发一个网站时,需要自定义404错误页面. 做法是这样的 在网站根目录下建立了一个404.html的错误页 ...

  6. 在Tomcat中配置404自定义错误页面详解

    这篇文章主要介绍了在Tomcat中配置404自定义错误页面全解,需要的朋友可以参考下 一直使用tomcat,今天想到一个问题,自定义404错误页面, 为了获得很好的用户感受,是不应当向用户暴露404这 ...

  7. ASP.NET Core中显示自定义错误页面

    在 ASP.NET Core 中,默认情况下当发生500或404错误时,只返回http状态码,不返回任何内容,页面一片空白. 如果在 Startup.cs 的 Configure() 中加上 app. ...

  8. ASP.NET全局错误处理和异常日志记录以及IIS配置自定义错误页面

    应用场景和使用目的 很多时候,我们在访问页面的时候,由于程序异常.系统崩溃会导致出现黄页.在通常的情况下,黄页对于我们来说,帮助是极大的,因为它可以帮助我们知道问题根源,甚至是哪一行代码出现了错误.但 ...

  9. MVC4 自定义错误页面(转)

    一.概述 MVC4框架自带了定义错误页,该页面位于Shared/Error,该页面能够显示系统未能捕获的异常,如何才能使用该页面: 二.使用步骤: 1.配置WebConfig文件,在System.We ...

随机推荐

  1. UML之结尾篇

    作为十期的孩子,我们已经开发过两个系统,学生管理系统和机房收费系统,也接触了软工,编写了一系列文档,不知道小朋友有没有这种感觉,开发一个系统软件和编写一个程序是不一样的,他们之间的差别,用一个比喻来说 ...

  2. Callable与Future

    本文可作为传智播客<张孝祥-Java多线程与并发库高级应用>的学习笔记. 在前面写的代码中,所有的任务执行也就执行了,run方法的返回值为空. 这一节我们说的Callable就是一个可以带 ...

  3. NIO模式例子

    NIO模式主要优势是体现在对多连接的管理,对众多连接各种事件的转发让处理变得更加高效,所以一般是服务器端才会使用NIO模式,而对于客户端为了方便及习惯使用阻塞模式的Socket进行通信.所以NIO模式 ...

  4. 第一个Polymer应用 - (0)准备工作

    原文链接:  Getting Started - Your first Polymer application翻译时间: 2014年7月5日翻译人员: 铁锚 关于Polymer 的简介,请参考 CSD ...

  5. LeetCode(34)-Palindrome Number

    题目: Determine whether an integer is a palindrome. Do this without extra space. 思路: 求一个整数是不是回文树.负数不是, ...

  6. ruby如何查找一个方法属于哪个类

    这是一个看似简单,实际不那么直接的问题.一种方法是先直接看当前对象的类是神马东东: puts self.class 或者 self.class.name 不过在某些情况下上述代码返回不了具体的名称,前 ...

  7. 高性能缓存系统Memcached在ASP.NET MVC中应用

    在Memcached中实体类型未经序列化不能在Memcached中缓存,因此需要对实体类进行处理,才能缓存下来. Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库 ...

  8. 重定向和servlet生命周期

    重定向(1)什么是重定向服务器通知浏览器向一个新的地址发送请求.注:可以发送一个302状态码和一个Location消息头.(该消息头包含了一个地址,称之为重定向地址),浏览器收到之后,会立即向重定向地 ...

  9. 在线学习Java免费资源推荐

    你想学习Java吗?来对地方了!这篇文章将会介绍很多高质量的免费资源,包括网页.论坛.电子书和速查表. Java是一种面向对象的编程语言,拥有独立.多线程.安全.动态和健壮的特点.归功于其多功能的特点 ...

  10. JTA 分布式事务

    什么是JTA - 2009-07-25 18:31:06|  分类: 技术文章|举报|字号 订阅     什么是JTA? Java Transaction API(Java事务API) (JTA)Ja ...