视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.net中自定义错误页面的实现升级篇
2020-11-27 22:35:01 责编:小采
文档


问题描述:

在上一篇博文 “.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 = 1,

 /// <summary>
 /// 请求失败
 /// </summary>
 Fail = -1,
 }

第二步:按照 上一篇博文: .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"] == 1) {
 //// 自定义请求成功逻辑处理
 //// 通过解析具体的ResultValue的值做相应的逻辑处理.....
 if (resultObj["ResultValue"]) {
 var doResult = resultObj["ResultValue"].split('^');
 if (doResult && doResult.length > 1) {
 if (doResult[0] == 1) {
 //// 说明处理成功,做相应的逻辑处理
 alert("处理成功!");
 } else {
 //// 处理失败
 alert(doResult[1]);
 }

 } 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));
 }

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

总结

下载本文
显示全文
专题