ASP.NET MVC : Action过滤器(Filtering)

http://www.cnblogs.com/QLeelulu/archive/2008/03/21/1117092.html

ASP.NET MVC : Action过滤器(Filtering)

相关文章:

  1. ASP.NET MVC URL Routing 学习
  2. AP.NET MVC : 控制器 和 控制器Actions
  3. ASP.NET MVC 学习: 视图

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

一些可能用到Action过滤器的地方有:

  • 日志
  • 身份验证和授权 - 限制用户的访问
  • 输出缓存 - 保存一个Action的结果
  • 网络爬虫的过滤
  • 本地化
  • 动态Action - 将一个Action注入到控制器中

实现一个Action过滤器

Action过滤器是通过继承ActionFilterAttribute类来实现的一个Attribute类。ActionFilterAttribute 是一个抽象类,提供了两个virtual的方法给我们重写,OnActionExecutingOnActionExecuted

ASP.NET MVC 框架会在调用Action方法之前调用你Action过滤器中的OnActionExecuting方法,在之后调用Action过滤器中的OnActionExecuted方法。当然在创建Action过滤器的时候你不需两个方法都实现。

下面的示例是在调用Action方法之前和之后的日志跟踪:

class LoggingFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext
        filterContext)
    {
        filterContext.HttpContext.Trace.Write("Starting: " + 
        filterContext.ActionMethod.Name);
    } 

    public override void OnActionExecuted(FilterExecutedContext
        filterContext)
    {
        if (filterContext.Exception != null)
        {
            filterContext.HttpContext.Trace.Write("Exception thrown");
        }
    }
}

Action Filter Context

OnActionExecuting方法有一个类型为FilterExecutingContext的参数,而OnActionExecuted方法有一个相应的类型为FilterExcutedContext的
参数。两个Context类都是继承自FilterContext类,而FilterContext类继承自ControllerContext类并包含
一个ActionMethod属性。你可以使用ActionMethod属性来坚定这个Action过滤器是应用到哪个Action方法上的。

FilterExecutingContext类包含一个 Cancel 的属性,允许你取消当前的Action。

FilterExcutedContext
类包含一个Exception属性和一个ExceptionHandled属性。如果Exception属性为null,则没有异常在action
stack中,表明Action方法运行并没有发生错误。如果Exception属性不为null,则过滤器知道该怎么处理,过滤器处理完异常后会发出已
经处理完的信号,然后将ExceptionHandled属性设为true。就算ExceptionHandled属性为true,堆栈中添加到其他
Action方法的OnActionExcetued方法将会照常被调用,这种场景就如就算一个异常被处理了,日志记录filter一样照常执行。

用过滤器特性(Attribute)来标记一个Action方法

你可以将过滤器应用到任何一个你喜欢的Action方法上。下面的示例演示一个控制器中包含的用Action过滤器Attribute标记的Action方法。

class HomeController : Controller
{
    [LoggingFilter]
    public void Index()
    {
        RenderView("Index");
    } 

    [LoggingFilter]
    public void About()
    {
        RenderView("About");
    } 

    [LoggingFilter]
    public void ClickMe()
    {
        HttpContext.Trace.Write("Button was clicked.");
        InvokeAction("Index");
    }
}

实现一个控制器范围的Action过滤器

ASP.NET MVC 控制器(Controller)类定义的OnActionExecuting 和
OnActionExcuted
方法你可以重写。当你重写一个或者这两个方法的时候,你实际上定义了一个将会应用到该控制器类中所有的Action方法的Action过滤器。严格来说,
这个方法没有构成一个Action过滤器,但不管怎样,她们提供的功能是相似的。
在下面的示例中,控制器级别的OnActionExecuting和OnActionExecuted方法应用到控制器中所有的Action方法中:

控制器范围的Action Filter


Action过滤器的作用范围

除了用Action过滤器标记一个Action方法外,你也可以用来标记一个完成的控制器类。如果这样的话,这个Action过滤器将会应用到该控制器的所有Action方法上。

另外,如果你的控制器类继承自别的控制器类,而基控制器类可能有它自己的Action过滤器Attributes。如果你在子类中重写了基控制器类的Action方法,则子类的该Action方法也会有它自己的从基类继承而来的Action过滤器Attributes。

Action过滤器的执行顺序

每一个Action过滤器都有一个 Order
属性,用来决定Action过滤器在该范围内的执行顺序。Order属性必需是0(默认值)或者更大的整数值。省略Order属性则会给该过滤器的
Order值为 -1, 表明为指明顺序。任何一个在同一范围的Action过滤器Order设为 -1
的都将按不确定的顺序执行,单在此之前过滤器有一个特定的顺序(注:下面会说到).

当设置Order属性的值的时候,必需指定一个唯一的值。如果两个或者更多的Action过滤器具有相同的Order属性值,将会抛出一个异常。

来看一个示例:

2)]
[Filter2(Order = 3)]
[Filter3(Order = 1)]
public void Index()
{
    RenderView("Index");
}

Filter的执行顺序为:Filter3 => Filter1 => Filter2.

在同一范围,Action过滤器按下面的顺序执行:

  • OnActionExecuting virtual method of the controller.
  • OnActionExecuting method of any filters that are applied to the current controller, in this order:
    • Base class
    • Any derived class
  • OnActionExecuting method of filters that are applied to the action method, in this order:
    • Base class
    • Derived class
  • Action method
  • OnActionExecuted method of filters that are applied to the action method, in this order:
    • Derived class
    • Base class
  • OnActionExecuted method of filters that are applied to the current controller, in this order:
    • Derived class
    • Base class
  • OnActionExecuted virtual method of the controller.

可以看到OnActionExecuted 和 OnActionExecuting 的执行顺序是反过来的。

Action过滤器执行顺序的示例

下面的示例演示了一个包含两个Action过滤器的MVC程序。DebugFilter 过滤器写trace信息,而ThrowExceptionFilter 过滤器引起一个异常。这个程序也包含一个基控制器和一个子控制器和一个视图。

DebugFilter 过滤器

下面的Action过滤器在调用的时候将会抛出一个异常:

class ThrowExceptionFilter : DebugFilterAttribute
{
    public override void 
        OnActionExecuting(
            System.Web.Mvc.FilterExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
        DebugFilterAttribute.StartDecrement();
        throw new InvalidOperationException(
            "Exception thrown by the filter");
    }
}

下面的是定义一个应用了Action过滤器的基控制器类:

"(CONTROLLER) MyBaseController", Order = 1)]
[DebugFilter(Message = "(CONTROLLER) MyBaseController", Order=2)]
public class MyBaseController : Controller
{
    [ControllerAction]
    [DebugFilter(Message = "(ACTION) MyBaseController.Index()", Order=2)]
    [DebugFilter(Message = "(ACTION) MyBaseController.Index()", Order=1)]
    public virtual void Index()
    {
        RenderView("Index");
    }
}

下面的是子控制器类,注意这里重写了OnActionExecuting 方法:

MyDerivedController

下面的是显示trace的视图页:

View

下面是程序运行时的输出结果:

Action Filter 1:  (PRE) MyDerviedController.OnActionExecuting VIRTUAL METHOD  
Action Filter 2:   (PRE) DebugFilter.OnActionExecuting - Order=1 Message=‘(CONTROLLER) MyBaseController
Action Filter 3:    (PRE) DebugFilter.OnActionExecuting - Order=2 Message=‘(CONTROLLER) MyBaseController
Action Filter 4:     (PRE) DebugFilter.OnActionExecuting - Order=1 Message=‘(CONTROLLER) MyDerivedController
Action Filter 5:      (PRE) DebugFilter.OnActionExecuting - Order=2 Message=‘(CONTROLLER) MyDerivedController
Action Filter 6:       (PRE) DebugFilter.OnActionExecuting - Order=1 Message=‘(ACTION) MyDerivedController.Index()
Action Filter 7:        (PRE) DebugFilter.OnActionExecuting - Order=2 Message=‘(ACTION) MyDerivedController.Index()
Action Filter 8:         (ACTION) MyDerivedController.Index()

时间: 2024-10-25 01:48:13

ASP.NET MVC : Action过滤器(Filtering)的相关文章

Asp.Net Mvc Action过滤器(二)

在Mvc中为Action添加过滤器,有两种方式, 一.使用ActionFilterAttribute,简单方式,同时支持Result的过滤处理, 1.可以为空,支持的重写:OnActionExecuted,OnActionExecuting,OnResultExecuted,OnResultExecuting 2.支持类定义或方法定义 3.不支持多个过滤器实例,我的理解是一个action只能指定一个过滤器,目前还没有验证. // // 摘要: // 表示筛选器特性的基类. [AttributeU

[翻译] 使用ASP.NET MVC操作过滤器记录日志

[翻译] 使用ASP.NET MVC操作过滤器记录日志 原文地址:http://www.singingeels.com/Articles/Logging_with_ASPNET_MVC_Action_Filters.aspx 翻译:Anders Liu 摘要:日志记录是一种常见的交错关注点(Cross-Cutting Concern),很多ASP.NET开发者会在Global.asax文件中处理它.由于MVC是构建在ASP.NET之上的,所以你可以使用同样的解 决方式,但还有更好的方法.这篇文章

ASP.NET MVC 全局过滤器(FilterConfig)、标记在控制器上和方法上的筛选器执行顺序

原文:ASP.NET MVC 全局过滤器(FilterConfig).标记在控制器上和方法上的筛选器执行顺序 FilterConfig->控制器上的筛选器-->方法上的筛选器(大-->小,上-->下) 全局-->控制器->个别 尝试的时候记得把返回true 1 protected override bool AuthorizeCore(HttpContextBase httpContext) 2 { 3 //return base.AuthorizeCore(httpC

ASP.NET MVC Action向视图传值之匿名类型

原文:ASP.NET MVC Action向视图传值之匿名类型 在使用ASP.NET MVC过程中想必大家都有遇到过一个问题就是我们的Action如何向视图传递匿名类型的值呢,如果不做特殊处理则无法实现. 接下来我们来看一个示例: 在我们的控制中: using System.Collections.Generic; using System.Web.Mvc; namespace TianYa.DotNetShare.MvcDemo.Controllers { public class DemoC

Sending JSON to an ASP.NET MVC Action Method Argument

Sending JSON to an ASP.NET MVC Action Method Argument 原文地址:https://www.cnblogs.com/chucklu/p/11650080.html

Asp.Net MVC在过滤器中使用模型绑定

废话不多话,直接上代码 1.创建MVC项目,新建一个过滤器类以及使用到的实体类: 1 public class DemoFiltersAttribute : AuthorizeAttribute 2 { 3 public override void OnAuthorization(AuthorizationContext filterContext) 4 { 5 var person = new Person(); 6 //过滤器中使用模型绑定 7 BindModel<Person>(filt

HTTP Modules versus ASP.NET MVC Action Filters

from:http://odetocode.com/blogs/scott/archive/2011/01/17/http-modules-versus-asp-net-mvc-action-filters.aspx Monday, January 17, 2011 ASP.NET MVC has action filters, while ASP.NET has HTTP modules. Inside their respective processing pipelines, these

ASP.NET MVC Action返回结果类型【转】

ASP.NET MVC 目前一共提供了以下几种Action返回结果类型: 1.ActionResult(base) 2.ContentResult 3.EmptyResult 4.HttpUnauthorizedResult 5.JavaScriptResult 6.JsonResult 7.FileResult (base) 8.FileContentResult 9.FilePathResult 10.FileStreamResult 11.RedirectResult 12.Redirec

asp.net mvc 利用过滤器进行网站Meta设置

过去几年都是用asp.net webform进行开发东西,最近听说过时了,同时webform会产生ViewState(虽然我已经不用ruanat=server的控件好久了 :)),对企业应用无所谓,但对于互联网应用就不太友好了,这几天学习了一下asp.net mvc,自己做了个网站玩玩(asp.net mvc + bootstrap + html5),随便也学习一下. 网站的组织: 三个网站分别为 index主站.Info信息咨询站.live视频站,利用Areas进行分开 namespace D