女朋友不是想抛就抛,但异常却可以,不信请往下看。

今天在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 = ;
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 = ;
Server.ClearError();
}
}

ajax客户端收到的结果如下:

从此,可以尽情地抛异常了。

想抛就抛:Application_Error中统一处理ajax请求执行中抛出的异常的更多相关文章

  1. Ajax请求过程中显示“进度”的简单实现

    Ajax在Web应用中使用得越来越频繁.在进行Ajax调用过程中一般都具有这样的做法:显示一个GIF图片动画表明后台正在工作,同时阻止用户操作本页面(比如Ajax请求通过某个按钮触发,用户不能频繁点击 ...

  2. angularjs中如何在异步请求执行完以后再执行其他函数?

    angularjs中如何在异步请求执行完以后再执行其他函数? 之前脑袋回路就是从上到下的执行js,直到有一次我的页面上已经显示了空才走到angularjs里的$http的成功回调函数里,然后才开始正视 ...

  3. 二、Ajax请求MVC中数据查询表返回datatable

    一.Ajax请求MVC中数据查询表返回datatable 解决方式 返回list

  4. ajax请求webservice时抛出终止线程的异常

    请求webservice中以下接口,会抛出异常 {"Message":"正在中止线程.","StackTrace":" 在 Sys ...

  5. 统一处理jquery ajax请求过程中的异常错误信息的机制

    当jQuery ajax向服务器发送请求,服务器发生异常,比如:400.403.404.500等异常,服务器将异常响应给客户端,此时的ajax可以获取异常信息并进行处理,但此时我们一般是跳转到与异常编 ...

  6. ajax请求过程中下载文件在火狐下的兼容问题

    项目中碰到的问题,记录如下. 需求很简单,点击一个文件链接下载该文件,同时向后台发送请求.需求很常见,用户点击下载后通常要进行下载量的统计,统计的话可以利用 script标签 或者 img标签(图片p ...

  7. aJax请求结果中包含form的问题

    jsp页面a.jsp如下: <form action='login' id='formId' method='post'> <input name='user'> </f ...

  8. Ajax 请求头中常见content-type

    四种常见的 POST 提交数据方式 HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范.规范把 HTTP 请求分为三个部分:状态行.请求头.消息主体.协议规定 POST ...

  9. 在springmvc框架中,通过ajax请求,响应至前端的中文显示是?

    今天遇到的一个问题,我通过ajax请求去访问控制器,然后通过控制器给我响应了一段json数据,但是里面的中文 在浏览上显示是??,我在web.xml 文件中是设置了编码过滤器的,但是估计这个编码过滤器 ...

随机推荐

  1. 【转】你真的理解Python中MRO算法吗?

    你真的理解Python中MRO算法吗? MRO(Method Resolution Order):方法解析顺序. Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多 ...

  2. android自定义进度圆与定时任务

    先看代码:自定进度圆 public class ProgressCircle extends View { private Paint paint; private int strokewidth = ...

  3. ted be grateful

    -------------------------------------------------------------- David Steindl-Rast: Want to be happy? ...

  4. 在本地机器上能访问tomcat,远程机器访问不了的解决方法

    问题描述:在测试服务器上搭建了一个tomcat,在测试服务器上能用ip打开tomcat.我用自己的机器能远程桌面能登录到测试服务器上,但在自己的机器上无法通过ip来访问测试服务器上的tomcat. 解 ...

  5. python计算机视觉——黑板客老师课程学习

    机器学习的一个应用方向,是如何让机器去理解图像.包括对图像里物体的识别,跟踪和测量. 能做什么——无人驾驶汽车.人脸识别.车牌识别手势识别(游戏方向) PIL静态的库 OpenCV 动态的库 impo ...

  6. Android消息推送——JPush极光推送

    刚看了一篇关于Android消息推送评测总结的博客http://www.cnblogs.com/logan/p/4514635.html: 自己也对原学过的JPush极光进行一下小结,方便后续工作使用 ...

  7. gdb调式

    1.PCB版的相应目录下执行命令: gdbserver 10.18.13.84:5555 DvdPlayer 2.linux操作系统执行:(如果是android找到android项目路径下的gdb)m ...

  8. Linux程序包管理初步-yum的使用

    何为yum? yum:由yellow dog研发,全称Yellowdog Update Modifier 是rhel系列系统上rpm包管理器的前端工具,可用来自动解决依赖关系,从而更好的实现程序包的安 ...

  9. (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程

    . . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...

  10. 清除浮动的 why

    如果你想第三个p不被前面的浮动层所影响,就对它进行清除如果没有清除,第三个层就会移到第一个p下面 记住!!浮动是用来布局的~你看你的网页设计图,好几个版块在一条线上就是要浮动了,不需要浮动就是版块跟前 ...