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

今天在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客户端收到的结果如下:

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

最新文章

  1. 【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案
  2. IO(六)--- 编码和解码
  3. 我的 GitHub 100 连击
  4. 使用 gulp 搭建前端环境入门篇(转载)
  5. FFmpeg.exe使用随笔
  6. HDU(3605),二分图多重匹配
  7. Eclipse + Idea + Maven + Scala + Spark +sbt
  8. java 调用 phantomjs
  9. android 18 Bundle类
  10. 【转】C#注册快捷键
  11. js各种进制数之间的转换
  12. 九度OnlineJudge之1017:还是畅通工程
  13. STM32 下的库函数和寄存器操作比较
  14. linux中普通的文件查看操作(cat、more、less、head、tail)
  15. 按钮JButton,单选按钮JRadioButton,复选框JCheckBox
  16. Linux command: grep
  17. yii源码三 -- db
  18. Linux IPC BSD socket编程基础
  19. IRanges package
  20. Web前端开发笔试&amp;面试_02(others)

热门文章

  1. 在Egret实现二维码长按识别
  2. JavaScript:JSON
  3. 使用fastcgi_finish_request提高页面响应速度
  4. JStrom的zk数据
  5. AX2012R2使用SQL Server2014安装报表扩展报错
  6. time时间处理
  7. Elasticsearch分布式搜索集群配置
  8. java break语句的三种用法
  9. cms替换主页的步骤
  10. vim--golang代码补全