想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常
2014-12-30 17:43
701 查看
女朋友不是想抛就抛,但异常却可以,不信请往下看。
今天在MVC Controller中写代码时,纠结了一下:
在这个地方要不要抛异常呢?
如果不抛异常,就得这么写:
而且通常在这样的情况下,还需要记录日志,于是代码变成:
如果抛异常呢,代码就可以这么写:
代码显得更简洁,更具表达力,而且记录错误日志可以在Application_Error中统一处理:
但这会带来一个问题,客户端收到的将是自定义500错误页面的html代码,不仅没有具体的错误信息,而且在ajax回调时还要额外处理,而通常我们最期待的是一个json格式的返回结果。
于是要想实现“想抛就抛”,就必须解决:如何在Application_Error中统一处理ajax请求处理过程中产生的异常,并将之转换成json格式的响应内容返回给客户端。
分解一下,就变成了2个问题:
1)如何在Application_Error中判断一个请求是否是ajax请求?
今天上午通过MVC的扩展方法IsAjaxRequest解决了,详见如何在Global.asax中判断是否是ajax请求:
2)如何生成json格式的响应内容并返回给客户端?
这个可以通过Json.NET+Response.Write来解决,代码如下:
最终实现“想抛就抛”的代码如下:
ajax客户端收到的结果如下:
从此,可以尽情地抛异常了。
今天在MVC Controller中写代码时,纠结了一下:
public async Task<ActionResult> Save(int? postId) { if(!IsOwner(postId.Value, userId)) { //抛不抛异常呢? } }
在这个地方要不要抛异常呢?
如果不抛异常,就得这么写:
public async Task<ActionResult> Save(int? postId) { if(!IsOwner(postId.Value, userId)) { return Json(new { isSuccess = false, message = "尝试执行未经授权的操作" }); } }
而且通常在这样的情况下,还需要记录日志,于是代码变成:
if(!IsOwner(postId.Value, userId)) { Logger.Default.Info("UnauthorizedSave", "..."); return Json(new { isSuccess = false, message = "尝试执行未经授权的操作" }); }
如果抛异常呢,代码就可以这么写:
if(IsOwner(postId.Value, userId)) { throw new UnauthorizedAccessException(); }
代码显得更简洁,更具表达力,而且记录错误日志可以在Application_Error中统一处理:
protected void Application_Error(Object sender, EventArgs e) { var lastError = Server.GetLastError(); if (lastError != null) { Logger.Default.Error("Application_Error", lastError); Response.StatusCode = 500; Server.ClearError(); } }
但这会带来一个问题,客户端收到的将是自定义500错误页面的html代码,不仅没有具体的错误信息,而且在ajax回调时还要额外处理,而通常我们最期待的是一个json格式的返回结果。
于是要想实现“想抛就抛”,就必须解决:如何在Application_Error中统一处理ajax请求处理过程中产生的异常,并将之转换成json格式的响应内容返回给客户端。
分解一下,就变成了2个问题:
1)如何在Application_Error中判断一个请求是否是ajax请求?
今天上午通过MVC的扩展方法IsAjaxRequest解决了,详见如何在Global.asax中判断是否是ajax请求:
if ((new HttpRequestWrapper(Request)).IsAjaxRequest()) { }
2)如何生成json格式的响应内容并返回给客户端?
这个可以通过Json.NET+Response.Write来解决,代码如下:
Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject( new { isSuccess = false, message = lastError.Message })); Response.Flush();
最终实现“想抛就抛”的代码如下:
protected void Application_Error(Object sender, EventArgs e)
{
var lastError = Server.GetLastError();
if (lastError != null)
{
CNBlogs.Infrastructure.Logging.Logger.Default.Error("Application_Error", lastError);
if(Request != null && (new HttpRequestWrapper(Request)).IsAjaxRequest())
{
Response.Clear(); Response.ContentType = "application/json; charset=utf-8"; Response.Write(Newtonsoft.Json.JsonConvert.SerializeObject( new { isSuccess = false, message = lastError.Message })); Response.Flush();
Server.ClearError();
return;
}
Response.StatusCode = 500;
Server.ClearError();
}
}
ajax客户端收到的结果如下:
从此,可以尽情地抛异常了。
相关文章推荐
- ajax和普通请求使用spring mvc在controller中的异常统一处理
- 使用RAISE_APPLICATION_ERROR抛出与oracle交互的异常
- Oracle PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
- ajax请求webservice时抛出终止线程的异常
- C# MVC 处理您的请求时发生异常。此外,对第一个异常执行自定义错误页时发生另一异常。已终止请求。
- XGoAjax,统一风格处理项目中的ajax请求
- Oracle 异常处理 raise_application_error sqlcode sqlerrm
- Spring MVC异常统一处理(包括普通请求异常以及ajax请求异常)
- try ,finally都抛出异常如何处理.如果try中抛出了异常,在控制权转移到调用栈上一层代码之前, finally 语句块也会执行,如果finally抛出异常,try语句快抛出的那个异常就
- 转-封装网络请求库,统一处理通用异常 (基于volley网络请求库)
- 统一处理jquery ajax请求过程中的异常错误信息的机制
- 【Oracle】PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
- 执行Web请求生成了未处理的异常
- 对象的当前状态使该操作无效 说明: 执行当前 Web 请求期间,出现未处理的异常。
- Ajax 请求session过期的统一处理
- 使用Spring实现异常统一处理【四】--error-page中对异常进行log
- SpringMVC对异常进行全局处理,并区分对待ajax和普通请求
- MVC 使用HandleErrorAttribute统一处理异常
- 解决$.ajax()请求异常~ jQuery提示parsererror错误解决办法
- 无法验证数据。执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息