首页 > 代码库 > MVC源码分析 - Action/Result 过滤器(续)

MVC源码分析 - Action/Result 过滤器(续)

上一篇 看到了Action/Result过滤器的执行顺序:

OnActionExecuting -> Action -> OnActionExecuted -> OnResultExecuting -> View-> OnResultExecuted

这一篇就来做几个例子吧.

一、Demo

上一篇 的代码可能并不怎么好懂. 首先, 我能在FilterConfig中注册过滤器, 可以在Controller中重写Action/Result过滤器或者是在Controller上标注过滤器特性, 还可以在方法上加上过滤器特性. 那么这些过滤器的执行, 都是在上一篇中的方法中执行的. 上一篇中, 并不能直观的看到这些顺序, 也是不好理解的点之一了.

但是上一篇提到过, 在调换顺序之后, 最先执行的应该是Controller里面的过滤器, 那么到底是不是这样呢?来看一下吧.

首先建几个过滤器, 都继承自 ActionFilterAttribute 类, 这里面有Action/Result的四个过滤器方法

//FilterConfig中注册使用
public class MyFilterConfigAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FilterConfigAttribute - OnActionExecuted<br />");
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FilterConfigAttribute - OnActionExecuting<br />");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FilterConfigAttribute - OnActionExecuted<br />");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FilterConfigAttribute - OnActionExecuting<br />");
    }
}

//Controller上标注此特性
public class MyControllerAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ControllerAttribute - OnActionExecuted<br />");
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ControllerAttribute - OnActionExecuting<br />");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ControllerAttribute - OnActionExecuted<br />");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ControllerAttribute - OnActionExecuting<br />");
    }
}

//Action上标注此特性
public class MyActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ActionAttribute - OnActionExecuted<br />");
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ActionAttribute - OnActionExecuting<br />");
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ActionAttribute - OnActionExecuted<br />");
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("ActionAttribute - OnActionExecuting<br />");
    }
}

然后就是在控制器和视图.

[MyController]
public class FootController : Controller
{
    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FootController - OnActionExecuted<br />");
    }

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FootController - OnActionExecuting<br />");
    }

    protected override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FootController - OnResultExecuted<br />");
    }

    protected override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("FootController - OnResultExecuting<br />");
    }

    [MyAction]
    public ActionResult Get()
    {
        Response.Write("<br /><br />Action 方法被执行<br /><br />");
        return View();
    }
}
@{
    ViewBag.Title = "Get";
}
<br />
<br />
Get - View视图被解析
<br />
<br />

准备妥当了, 上结果:

技术分享

从以上结果中可以看出, 最先执行的, 是Controller里面的ActionExecuting方法.

这里的执行顺序, 有点类似递归的执行过程. 从这个结果来看上一篇的执行过程, 就很清晰了.

Controller内部Action/Result过滤器 - > FilterConfig注册Action/Result过滤器 - > Controller标注Action/Result特性 - > Action标注Action/Result特性

目录已同步

MVC源码分析 - Action/Result 过滤器(续)