asp.net MVC3 仿照博客园功能 异常处理

这几天感觉我自己比较懒,除了偶尔的写了一点博客以外,对于那个重要的仿照博客园功能的项目我竟然忘记更新了。失误了,天天脑子里的事太多了,有点乱,程序员,伤不起啊。
还是不能不谦虚啊,今天继续项目的开发,不做那些费时的工作了,那个等我星期休息的时候再做,今天来做一个异常处理的功能。
    众所周知,在asp.net世界中,对于异常的处理就是try catch,当然这个是在方法内部,还有Page_Error 页面级别的错误,

application_error 应用程序级别的错误,这几个地方可以用来处理异常信息。一般情况下,

我们对于已知的可能出现的错误会直接在try  catch中捕获并且处理,但是对于那些我们没有考虑到的异常信息,我们就要采取别的办法了,

比如定义一个基类,用来处理子类抛出的异常,然后在可能出现异常信息的地方继承该类,让父类处理子类中不能确定的并且是抛出的未处理的异常信息。

这个和验证用户是否登陆的方式基本一样,对于某些资源,需要有权限的用户才能访问,我们就会定义一个基类,用来验证用户是否登陆,

如果登陆才可以继续执行,否则就要跳转到登陆界面。
当然,前面说的处理异常的方式是在web form时代我们(起码是我)常用的方式,但是在MVC 时代到临的时候,这些处理是否更容易呢?

答案是肯定的,因为技术是在不断进步的嘛。
在MVC中我们对于已知的异常信息仍然会采用try catch的方式,并且是很常用的方式,但是对于验证用户登陆或者catch未捕获的异常信息

(当然我的意思是catch(exception ex)   在catch最后没有这一条,或者说有这一句,但是把异常信息进行了抛出处理),我们有了更容易实现的方式。

下面让我们一起走进如何使用MVC处理异常信息。
在软件架构不断发展的同时,设计模式也有了很多变种,AOP(面向切面编程或面向方面编程)就是一个变种的设计模式,对于设计模式的学习,

我个人不推荐死记硬背,我希望可以了解每种模式的意义,然后在项目中不要刻意的去使用它,而是在重构的时候进行,

这样我们可以更加深入的了解设计模式背后包含的含义。举个例子,单例模式是一个经典的设计模式,它可以保证类的实例只有一个,

但是如果我们不正确的使用这种方式,有时候会带来负面效果,比如多线程同时访问,只有在保证加锁、解锁的情况下可以保证,

但是在普通情况下就会出现意想不到的错误信息。
面向对象编程具有继承性,这应该是面向对象三大特性之一,这是类的垂直方面的编程工作,有上下级或父子关系,AOP是水平方面的编程,

它可以保证在开始之前或结束之后进行,不会破坏里面的结构。个人粗浅理解。
在MVC 3中对AOP的支持就表现在filter  过滤器上,他可以保证在开始之前或结束之后进行。

对于异常的处理我们采用的是自定义异常处理信息继承自IExceptionFilter,当然在MVC总内置了一个HandleErrorAttribute也可以用来捕获异常,

但是我们自己来控制可能会更好一些。

首先我们在HomeController的Index方法中抛出一个异常信息

 1  public ActionResult Index(int? id, int pageSize = 20)
 2         {
 3             List<BlogInfo> blogList = BlogServices.GetAllBlogList().ToPagedList<BlogInfo>(id == null ? 1 : Convert.ToInt32(id), pageSize);
 4             ViewBag.BlogList = blogList;
 5             if (Request.IsAjaxRequest())
 6             {
 7
 8             }
 9
10                 throw new HttpException(500, "");//抛出异常信息
11
12
13             return View(blogList);
14         }
15   //404Not Found
16         public ActionResult NotFound()
17         {
18             return View();
19         }
20         //内部服务器错误 500
21         public ActionResult InternalError()
22         {
23             return View();
24         }

2.设置自定义处理异常类

 1  public class CustomExceptionAttribute :FilterAttribute,IExceptionFilter   //HandleErrorAttribute
 2     {
 3
 4         public  void OnException(ExceptionContext filterContext)
 5         {
 6             if (filterContext.ExceptionHandled == true)
 7             {
 8                 HttpException httpExce = filterContext.Exception as HttpException;
 9                 if (httpExce.GetHttpCode() != 500)//为什么要特别强调500 因为MVC处理HttpException的时候,如果为500 则会自动
10                     //将其ExceptionHandled设置为true,那么我们就无法捕获异常
11                 {
12                     return;
13                 }
14             }
15             HttpException httpException = filterContext.Exception as HttpException;
16             if (httpException != null)
17             {
18                 filterContext.Controller.ViewBag.UrlRefer = filterContext.HttpContext.Request.UrlReferrer;
19                 if (httpException.GetHttpCode() == 404)
20                 {
21                     filterContext.HttpContext.Response.Redirect("~/home/notfound");
22                 }
23                 else if (httpException.GetHttpCode() == 500)
24                 {
25                     filterContext.HttpContext.Response.Redirect("~/home/internalError");
26                 }
27             }
28             //写入日志 记录
29             filterContext.ExceptionHandled = true;//设置异常已经处理
30         }
31     }

在这里我要多说一句,有些园友可能遇到这么一个问题,就是抛出了一个500的内部服务器异常,但是在自定义异常信息中就是无法捕获到,是什么原因呢?
其实就是MVC对500 的特殊照顾,在HttpException的httpCode为500的时候,MVC框架会自动的处理,然后将其ExceptionHandled设置为true。
对于其他的异常状态码,比如404就没有这样的照顾,所以500我们要优先照顾呀。
3.在设置好了自定义异常处理以后,我们可以在每个Action或Controller中进行注入,但是在MVC 3 中提供了另外一种可以全局注入的方式,那就是全局Filter,我一般叫做全局筛选器。这样就相当于我们在所有的Action上都进行了注入。
在global.asax中,进行全局注册
1  public static void RegisterGlobalFilters(GlobalFilterCollection filters)
2         {
3             filters.Add(new CustomExceptionAttribute(),1);//自定义的验证特性
4             filters.Add(new HandleErrorAttribute(),2);
5         }

4.我们在设置了自定义异常处理以后,会跳转到对应的页面,里面的信息相信大家都可以自己定制了

5.有图有证据  先来一个404异常处理信息

我请求的页面是home/index,然后自动跳转到了notFound页面
还有500错误,如果您不注意判断一个这个错误,那么你是不可能的

总结一下,在MVC中处理异常有很多中方式,HandleErrorAttribute,自定义异常处理类(重写IExceptionFilter或者是HandleErrorAttribute 的OnException方法),传统的try catch方法,这些都可以,除去那个try catch,其实自定义异常处理就是Filter的体现,和登陆验证没有任何区别。
还有一点就是HttpException的HttpCode为500的情况,ExceptionHandled会被自动设置为true,需要特殊照顾一下。
在我们处理完了异常以后,一定要将其ExceptionHandled设置为true,这样可以避免父类或者更高一级的异常处理捕获处理该异常信息。
MVC处理异常就是这么简单,Filter特性就是那么强大,让我们拥抱MVC,拥抱filter。
我看到有位大牛的MVC 4 书籍已经可以预定了,先试读一下,可以的话买一本,支持国产大牛,丰富一下自己。不是做广告,是发牢骚,什么时候能轮到我出书呢。
时间: 2024-10-10 21:24:53

asp.net MVC3 仿照博客园功能 异常处理的相关文章

博客园 功能添加 统计访问量

方式1: #使用amazingcounters 步骤1:注册账号 http://www.amazingcounters.com/sign-up.php 步骤2: 选择counter的风格. 步骤3: 填写网页的info.(关键是Site URL ) 步骤4: 把Counter的代码拷贝到博客园的 "管理" -> "设置" 选项,在公告编辑栏中添加你的HtmlCode,比如我的是: <div align="center"><

CSS:仿写博客园写一个静态网页

要求:一个小时仿照博客园的格局,写一个静态的网页,主要采用HTML+CSS+DIV的布局方式, 新建两个文件:website.html.website.css website.html代码如下: <!doctype html> <html lang="zh-CN"> <head> <meta charset="ansi"> <media name="description" content=&

博客园山寨版(asp.net mvc 开源)

一 源码地址 github:https://github.com/songboriceboy/cnblogsbywojilu 二 网站实例 www.douyuehan.com 三 技术选型 采用wojilu开发框架(www.wojilu.com) 为何要采用wojilu框架: 我记录框架除了提供以下快速开发组件之外,还提供了一个庞大的SNS示例源码,博客,论坛,CMS功能应有尽有.相比微软的MVC框架,提供了一个很好的教学示例.学完微软的asp.net mvc,可能你只会写一些简单的增删改查系统

js 多个checkedBox分组互斥功能实现 由于QQ邮件无法发送暂且将js写在博客园

今天有一项目需要实现多个checkbox分组实现组内互斥功能 . 具体要求如下:大的分类分为A B C 三类, 其中 A   B 中又分为 A1 A2 A3   B1 B2 B3  二级分类,二级分类下又有 A11  A12 A13 A14  A21 A22 A31 A32  B11 B12 B13 B14 ... .要求实现 A B C 互斥 A1 A2 A3 B1 B2 B3 组内互斥.具体结构及代码如下 具体功能树如下: A A1 A11 A12 A13 A2 A21 A22 A3 A31

博客园 打赏功能设置,友言,友荐,分享功能设置

一.jiaThis 分享到设置 <!-- JiaThis Button BEGIN --><script type="text/javascript" src="http://v3.jiathis.com/code/jiathis_r.js?move=0&btn=r5.gif" charset="utf-8"></script><!-- JiaThis Button END --> 二.友荐

在Web微信应用中使用博客园RSS以及Quartz.NET实现博客文章内容的定期推送功能

本篇随笔介绍在Web微信应用中使用博客园RSS以及Quartz.NET实现博客文章内容的定期推送功能,首先对Quartz.NET进行一个简单的介绍和代码分析,掌握对作业调度的处理,然后对博客园RSS内容的处理如何获取,并结合微信消息的群发接口进行内容的发送,从而构建了一个在Web应用中利用作业调度来进行消息发送的业务模型. Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)

ASP.NET Hashtable输出JSON格式数据 - 贵源网络 - 博客园

ASP.NET Hashtable输出JSON格式数据 - 贵源网络 - 博客园 ASP.NET Hashtable输出JSON格式数据 ASP.NET Hashtable输出JSON格式数据 - 贵源网络 - 博客园

打赏:关于博客园打赏的功能

今天在网上浏览资料的时候,发现别的博主都有打赏功能了,感觉很好奇,试了试几种方法,最后也把这个博客园的打赏功能弄出来了.大家好奇么,想知道怎么做到的朋友,请留言~~~ 欧耶欧耶~~~

Android 博客园客户端 (二) 新界面&amp;部分功能

重新创建项目(Android 4.2.2+):https://github.com/ZhangTingkuo/AndroidCnblogs.git 原项目(Android 4.1.2+):https://github.com/ZhangTingkuo/Cnblogs.git 原项目的界面看着很不爽,就只写了部分功能,然后决定重新设计界面,并把这部分功能添加进来,然后继续进行开发. 已经完成博客列表部分的显示 第一次做一个android项目,只为兴趣. 很多东西看起来貌似很简单,但是真的做的时候就