过滤器

MVC有4种过滤器。

过滤器             接口                        默认实现

Authorization    IAuthorizationFilter    AuthorizeAttribute

Action              IActionFilter            ActionFilterAttribute

Result              IResultFilter             ActionFilterAttribute

Exception         IExceptionFilter         HandleErrorAttribute

 

在生成过滤器时,可以直接实现过滤器的接口;也可以派生自默认实现,再重载里面的处理方法。

一、动作和结果过滤器(Action和Result)

动作过滤器内的方法有两个:

OnActionExecuting()

OnActionExecuted()

结果过滤器内的方法有两个:

OnResultExecuting()

OnResultExecuted()

执行时,在使用了过滤器的动作方法之前先执行OnActionExecuting(),然后执行动作方法,最后执行OnActionExecuted()。

再然后,开始执行OnResultExecuting(),接着执行动作方法中返回的视图(实际就是ActionResult大类),最后执行OnResultExecuted()。

 

例,新建MVC3项目13-21MvcFilters,在解决方案中新建目录 Infrastructure -> Filters,在此存放要建立的各个过滤器的类文件。

1、直接实现Action过滤器接口和Result过滤器接口

两个类放在一个文件中。

namespace _13_21MvcFilters.Infrastructure.Filters
{
    public class MyActionFilterAttribute : FilterAttribute, IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ... ...
        }
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
            ... ...
        }
     }

    public class MyResultFilterAttribute : FilterAttribute, IResultFilter
    {
        public void OnResultExecuting(ResultExecutingContext filterContext)
        {
            ... ...
        }
        public void OnResultExecuted(ResultExecutedContext filterContext)
        {
            ... ...
        }
     }
}

 

2、也可以派生自动作、结果过滤器接口的默认实现ActionFilterAttribute

编写ActionFilterAttribute的派生类,然后重载里面的OnActionExecuting()、OnActionExecuted()、OnResultExecuting()、OnResultExecuted()方法。

namespace _13_21MvcFilters.Infrastructure.Filters
{
    public class ProfileAllAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            ... ...
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            ... ...
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
           ... ...
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            ... ...
        }
    }
}

 

例,在Infrastructure/Filters下新建类文件ProfileAllAttribute.cs,内容如下: 

namespace _13_21MvcFilters.Infrastructure.Filters
{
    public class ProfileAllAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write(
                string.Format("OnActionExecuting<br>"));
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write(
                string.Format("OnActionExecuted<br>"));
        }

        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            filterContext.HttpContext.Response.Write(
                string.Format("OnResultExecuting<br>"));
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write(
                string.Format("OnResultExecuted<br>"));
        }
    }
}

新建控制器HomeController:

namespace _13_21MvcFilters.Controllers
{
    public class HomeController : Controller
    {
       
        [ProfileAll]
        public ActionResult Index()
        {
            Response.Write("Action Method is running...<br>");
            return View();
        }
    }
}

添加视图Index.cshtml:

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

 结果显示为:

 

3、全局过滤器;同一个过滤器带参数重复施加在一个动作方法上;施加在同一个动作方法上的过滤器执行顺序

(1)在Infrastructure/Filters目录下,定义过滤器如下:

namespace _13_21MvcFilters.Infrastructure.Filters
{
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]
    public class SimpleMessageAttribute : ActionFilterAttribute
    {
        public string Message { get; set; }

        public override void OnActionExecuting(ActionExecutingContext fileterContext)
        {
            fileterContext.HttpContext.Response.Write(
                string.Format("[OnActionExecuting:{0}]<br>", Message));
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.HttpContext.Response.Write(
                string.Format("[OnActionExecuted:{0}]<br>", Message));
        }
    }
}

如果要在同一个Action method上重复使用一个过滤器,那么在定义该过滤器时,需要加上属性:

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)]

如果没有此属性,会产生Duplicate attribute错误。

 

(2)在HomeController的Index()动作方法上,以注解属性使用过滤器:

namespace _13_21MvcFilters.Controllers
{
    public class HomeController : Controller
    {
        [SimpleMessage(Message = "A", Order = 1)]
        [SimpleMessage(Message = "B", Order = 2)]
        public ActionResult Index()
        {
            Response.Write("Action Method is running...<br>");
            return View();
        }
    }
}

 

Index.cshtml视图为:

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

 

(3)在Global.asax中,将过滤器SimpleMessageAttribute注册为全局过滤器,成为全局过滤器后,不需要显式的用注解属性来使用它,所有的动作方法都会自动施加该过滤器。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
            filters.Add(new SimpleMessageAttribute() { Message = "Global" , Order = 1});
        }

 

这样一来,施加在HomeController中,动作方法Index上的过滤器就相当于有3处,他们都设定了Order,按照Order的升序依次执行。最先执行的是全局过滤器。

如果没有设置Order,最先执行的是全局过滤器,而按照注解属性来使用的过滤器,执行顺序是不确定的(并不是按照出现的先后顺序来执行)

 

-lyj

转载于:https://www.cnblogs.com/brown-birds/p/3770261.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值