一、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的更多相关文章

  1. [转]ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)

    有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器.Action过滤器是自定义的Attributes,用来标记添 ...

  2. 通过源码了解ASP.NET MVC 几种Filter的执行过程

    一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多人觉得平时根本不需要知道这些,会用就行了.其实阅读源 ...

  3. ASP.NET MVC内置的Filter实现介绍

    有时候你想在调用action方法之前或者action方法之后处理一些逻辑,为了支持这个,ASP.NET MVC允许你创建action过滤器.Action过滤器是自定义的Attributes,用来标记添 ...

  4. ASP.NET MVC 几种 Filter 的执行过程源码解析

    一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神的工作,而且很多 人觉得平时根本不需要知道这些,会用就行了.其实阅读 ...

  5. Forms Authentication in ASP.NET MVC 4

    原文:Forms Authentication in ASP.NET MVC 4 Contents: Introduction Implement a custom membership provid ...

  6. 【ASP.NET MVC系列】浅谈ASP.NET MVC资源过滤和授权

    最近比较忙,博客很久没更新了,很多博友问何时更新博文,因此,今天就花了点时间,写了本篇文章,但愿大家喜欢. 本篇文章不适合初学者,需要对ASP.NET MVC具有一定基础. 本篇文章主要从ASP.NE ...

  7. 通过源码了解ASP.NET MVC 几种Filter的执行过程 在Winform中菜单动态添加“最近使用文件”

    通过源码了解ASP.NET MVC 几种Filter的执行过程   一.前言 之前也阅读过MVC的源码,并了解过各个模块的运行原理和执行过程,但都没有形成文章(所以也忘得特别快),总感觉分析源码是大神 ...

  8. ASP.NET MVC 入门9、Action Filter 与 内置的Filter实现(介绍)

    原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/09/1307660.html 有时候你想在调用action方法之前或者action方法之后处 ...

  9. ASP.NET MVC 拦截器IResultFilter

    在ASP.NET MVC中,有一个Result拦截器,实现ResultFilter需要继承一个类(System.Web.Mvc.FilterAttribute)和实现一个类(System.Web.Mv ...

随机推荐

  1. padding属性

    p {padding:2cm 4cm 3cm 4cm;} 属性定义及使用说明 padding简写属性在一个声明中设置所有填充属性.该属性可以有1到4个值. 实例: 填充:10px 5px 15px 2 ...

  2. MySQL8.0的安装与配置(Windows 10)

    MySQL的下载 进入MySQL官网 https://www.mysql.com/ 选择 DOWNLOAD 到页面底部找到 MySQL Community Edition (GPL) 找到MySQL ...

  3. 编程学习笔记(第三篇)面向对象技术高级课程:绪论-软件开发方法的演化与最新趋势(3)软件开发的现状、UML扩展

    一.软件开发的现状 软件领域正在发生一个巨变,特别是近几年来,软件领域正在发生翻天覆地的变化. 这一变化主要以这个云 + 端大数据, 这些是随着目前最先进的一些技术的产生而产生的. 随着这些新的技术以 ...

  4. Maximum Average Subarray I LT643

    Given an array consisting of n integers, find the contiguous subarray of given length k that has the ...

  5. EditText输入小数

    edtValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);

  6. SQL 存储过程调用存储过程

    研究一个别人做的项目代码看到数据库里有一段存储过程调用存储过程的代码,原来的代码比较复杂. 于是自己打算写一个简单的例子学习一下. 一.首先创建了被需要被调用的存储过程. USE [MSPetShop ...

  7. 【NIFI】 Apache NiFI 与 SQL 操作

    本里需要基础知识:[NIFI] Apache NiFI 安装及简单的使用 查询SQL 1.拖入一个 Processor:ExecuteSQLRecord(执行sql记录) 2.配置,SETTINGS的 ...

  8. 【Linux】CentOS 7.4 安装 MySQL 8.0.12 解压版

    安装环境/工具 1.Linux(CentOS 7.4版) 2.mysql-8.0.12-el7-x86_64.tar.gz 安装步骤 参考:https://dev.mysql.com/doc/refm ...

  9. 一窥kbmmw中的 smart service

    在kbmmw 的新版中(还没有发布),将会有一个叫做smart service 的服务.这种服务的属性基于服务器端,并且可以自动注册服务名,下面就是一个简单例子代码.这个服务里面有有三个发布的函数:e ...

  10. iOS知识基础篇--@property,@synthesize, nonatomic,atomic,strong,weak,copy,assign,retain详解

    一.@property 这个关键词的唯一作用就是声明getter.setter方法接口. 二.@synthesize 实现setter.getter方法,找不到实例变量则主动创建一个. 三.nonat ...