ASP.NET MVC IActionFilter IResultFilter IExceptionFilter/HandleError
一、IActionFilter
1、基本定义
在action的执行前后进行AOP拦截。
IActionFilter接口定义如下:
public interface IActionFilter
{
//执行方法之前
void OnActionExecuted(ActionExecutedContext filterContext); //----> ActionInvoke(xxxx) <-----执行Actin方法
//执行方法之后
void OnActionExecuting(ActionExecutingContext filterContext);
}
2、实现方式
(1)、控制器重写IActionFilter实现方法
控制器已经实现了接口IActionFilter,每次请求都会创建一个Controller实例,而且只执行一个Action方法,所以可以在控制器层次进行拦截,这样重载了的控制器的每个Action都会被拦截,Controller的定义如下:
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable,IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
所以,我们只需要重写已经实现的IActionFilter的两个方法,如下:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var contrllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName; var actionName = filterContext.ActionDescriptor.ActionName; var parameter = filterContext.ActionDescriptor.GetParameters(); filterContext.HttpContext.Response.Write(contrllerName + "_" + actionName); base.OnActionExecuting(filterContext);
} protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
}
(2)、定义一个FilterAttribute
定义Attribute放到不同的Action
public class MyCustomAttribute : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{ } public void OnActionExecuting(ActionExecutingContext filterContext)
{
//1.如果result不为空,那么就return了。不执行递归。。。
filterContext.Result = new ViewResult()
{
ViewName = "Error"
};
}
}
(3)、Global全局注入
每一个action上面加特性,比较麻烦,我们可以选择进行全局的注入。
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute()); filters.Add(new MyCustomAttribute());
}
二、IResultFilter
1、基本概念
Action的返回值有几下几种,他们都是继承自ActionResult,其主要作用是对Action的执行结果进行转换,如利用内容协商,把结果数据序列化为指定格式的数据。
ActionView、 ViewResult、JsonResult、ContentResult
ActionResult定义如下:
public abstract class ActionResult
{
public abstract void ExecuteResult(ControllerContext context);
}
在ActionResult的执行(调用ExecuteResult方法)前后进行AOP拦截。
接口定义如下:
public interface IResultFilter
{
void OnResultExecuted(ResultExecutedContext filterContext);
void OnResultExecuting(ResultExecutingContext filterContext);
}
2、实现方式
同IActionFilter一样,有三种方式
(1)、Controller上Override的
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable,IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
public class HomeController : Controller
{
protected override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
} protected override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}
}
(2)、继承FilterAttribute,IResultFilter或ActionFilterAtrribute
public class MyActionFilterAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnResultExecuting(filterContext);
} public override void OnResultExecuted(ResultExecutedContext filterContext)
{
base.OnResultExecuted(filterContext);
}
(3)、GlobleFilters 全局的注册
同IActionFilter
三、 IExceptionFilter HandleError
1、基本概念
IExceptionFilter定义如下
public interface IExceptionFilter
{
void OnException(ExceptionContext filterContext);
}
public abstract class Controller : ControllerBase, IActionFilter, IAuthenticationFilter, IAuthorizationFilter, IDisposable,IExceptionFilter, IResultFilter, IAsyncController, IController, IAsyncManagerContainer
Controller抽象类,接口IExceptionFilter的实现,空的
protected virtual void OnException(ExceptionContext filterContext)
{
}
HandleError是IExceptionFilter在MVC中的默认实现,也是默认注册在全局
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}
}
HandleError当出现异常时候,转到一个错误页面,其源代码如下:
public virtual void OnException(ExceptionContext filterContext)
{
if (filterContext == null)
throw new ArgumentNullException(nameof (filterContext));
if (filterContext.IsChildAction || filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
return;
Exception exception = filterContext.Exception;
if (new HttpException((string) null, exception).GetHttpCode() != || !this.ExceptionType.IsInstanceOfType((object) exception))
return;
string controllerName = (string) filterContext.RouteData.Values["controller"];
string actionName = (string) filterContext.RouteData.Values["action"];
HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
ExceptionContext exceptionContext = filterContext;
//构造一个ViewResult,跳转到其对应View页面
ViewResult viewResult1 = new ViewResult();
viewResult1.ViewName = this.View;
viewResult1.MasterName = this.Master;
viewResult1.ViewData = (ViewDataDictionary) new ViewDataDictionary<HandleErrorInfo>(model);
viewResult1.TempData = filterContext.Controller.TempData;
ViewResult viewResult2 = viewResult1;
exceptionContext.Result = (ActionResult) viewResult2;
//ExceptionHandled标记已经处理
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
//定义500错误
filterContext.HttpContext.Response.StatusCode = ;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
public string View
{
get
{
//view为空就是Error页面,Share文件夹下的Error.cshtml
if (string.IsNullOrEmpty(this._view))
return "Error";
return this._view;
}
set
{
this._view = value;
}
}
2、扩展例子
不仅要错误页面,还要记录日志到数据库
public class MyHandleErrorAttribute : FilterAttribute, IExceptionFilter// HandleErrorAttribute
{
public void OnException(ExceptionContext filterContext)
{
//记录日志。。。。my logic
filterContext.ExceptionHandled = true;
//这个要设置为true,要不会继续抛出异常
base.OnException(filterContext);
}
}
public class HomeController : Controller
{
[MyHandleError]
public ActionResult Index()
{
throw new Exception("");
return View();
}
}
配置Web.config
<configuration>
<system.web>
<customErrors mode="On"/>
</system.web>
</configuration>
可以直接跳到错误页面,要不直接显示红色的错误,黄色页。
ASP.NET MVC IActionFilter IResultFilter IExceptionFilter/HandleError的更多相关文章
- [转]ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)
有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器.Action过滤器是自定义的Attributes,用来标记添 ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...
- ASP.NET MVC内置的Filter实现介绍
有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器.Action过滤器是自定义的Attributes,用来标记添 ...
- ASP.NET MVC 几种 Filter 的执行过程源码解析
一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多 人觉得平时根本不需要知道这些,会用就行了.其实阅读 ...
- Forms Authentication in ASP.NET MVC 4
原文:Forms Authentication in ASP.NET MVC 4 Contents: Introduction Implement a custom membership provid ...
- 【ASP.NET MVC系列】浅谈ASP.NET MVC资源过滤和授权
最近比较忙,博客很久没更新了,很多博友问何时更新博文,因此,今天就花了点时间,写了本篇文章,但愿大家喜欢. 本篇文章不适合初学者,需要对ASP.NET MVC具有一定基础. 本篇文章主要从ASP.NE ...
- 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”
通过源码了解ASP.NET MVC 几种Filter的执行过程 一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...
- ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)
原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/09/1307660.html 有时候你想在调用action方法之前或者action方法之后处 ...
- ASP.NET MVC 拦截器IResultFilter
在ASP.NET MVC中,有一个Result拦截器,实现ResultFilter需要继承一个类(System.Web.Mvc.FilterAttribute)和实现一个类(System.Web.Mv ...
随机推荐
- BZOJ1925或洛谷2467 [SDOI2010]地精部落
BZOJ原题链接 洛谷原题链接 先讲下关于波动数列的\(3\)个性质. 性质\(1\):对于数列中的每一对\(i\)和\(i + 1\),若它们不相邻,那么交换这两个数形成的依旧是一个波动数列. 性质 ...
- 发送邮件--MFMailComposeViewController
只能在真机使用. 模拟器没有E-mail发送功能.无法调用 #import "EmailViewController.h" #import <UIKit/UIKit.h> ...
- BZOJ 3123 [SDOI2013] 森林 - 启发式合并 主席树
Description 给你一片森林, 支持两个操作: 查询$x$到$y$的$K$大值, 连接两棵树中的两个点 Solution 对每个节点$x$动态开权值线段树, 表示从$x$到根节点路径上权值出 ...
- MFC窗口位置和大小的获取
最近在做一个项目,需要控件随对话框大小的变化而变化,因此需要准确获取对话框窗口.控件的大小和位置. 经过好一番查寻.测试,终于看到了希望.下面是一些获取窗口位置和大小的函数,示例如下: 1.获取屏幕分 ...
- 品味性能之道<十一>:JAVA中switch和if性能比较
通常而言大家普遍的认知里switch case的效率高于if else.根据我的理解而言switch的查找类似于二叉树,if则是线性查找.按照此逻辑推理对于对比条件数目大于3时switch更优,并且对 ...
- 找不到类SimpleJdbcTemplate ParameterizedRowMapper cannot be resolved
找不到类SimpleJdbcTemplate 背景 想编译个web应用,原来spring-jdbc.jar用的是Spring 3.1,今天改成用Spring 4.3,报了这个错误. 现象 编译不通过, ...
- Twitter 相关APP开发
首先要获取 Consumer Key (API Key), Consumer Secret (API Secret):最好申请Access Token 和Access Token Secret,不然验 ...
- 经典矩阵快速幂之二-----hdu2157(走k步到
题意:(中问题,题意很简单 思路:a走k步到b,其实就是A^k,ans.mat[a][b]就是答案. 其实就是离散的邻接矩阵那个P(不想证明,逃 #include<cstdio> #inc ...
- Github 快速上手实战教程
一.实验介绍 1.1 实验内容 本次课程讲的是在实验楼的在线环境中,如何使用 Github 去管理在在线环境中使用的代码.配置.资源等实验相关文件,怎样去添加.同步和下拉在远程仓库中的实验文件,以此来 ...
- 常用.bat
休眠.bat rundll32 powrprof.dll,SetSuspendState 常用.bat start /d "d:\Program Files (x86)\Tencent\T ...