【问题标题】:should custom action filter inherit FilterAttribute?自定义动作过滤器应该继承FilterAttribute吗?
【发布时间】:2017-04-27 19:31:23
【问题描述】:

据我所知,每个动作过滤器都应该继承 IActionFilter 和 FilterAttribute。 例如:

public class ActionSpeedProfilerAttribute : FilterAttribute, IActionFilter 
{ 
     public void OnActionExecuted(ActionExecutedContext filterContext) 
     { 
         throw new NotImplementedException(); 
     }
    public void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
         throw new NotImplementedException(); 
     } 
}

http://www.dotnetcurry.com/aspnet-mvc/976/aspnet-mvc-custom-action-filter

但在 ASP.NET .Core 的 Microsoft 教程中,我们有没有 FilterAttribute 的示例:

public class SampleActionFilter : IActionFilter
    {
        public void OnActionExecuting(ActionExecutingContext context)
        {
            // do something before the action executes
        }

        public void OnActionExecuted(ActionExecutedContext context)
        {
            // do something after the action executes
        }
    }

https://docs.microsoft.com/pl-pl/aspnet/core/mvc/controllers/filters

那么我们是否应该继承FilterAttribute?

【问题讨论】:

  • 如果你想创建一个 ActionFilter 只需继承已经实现 IActionFilter-interface 的 ActionFilterAttribute。然后根据您的需要覆盖例如 OnActionExecuting-method。
  • @Esko 好的,但我也想知道使用 IActionFilter 时 FilterAttrubute 发生了什么。

标签: c# asp.net asp.net-mvc


【解决方案1】:

如果您只想全局添加过滤器(在FilterConfig 中),则不需要使用FilterAttribute,如下所示:

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new SampleActionFilter());
    }
}

...这将使每个操作都执行此过滤器,因为它实现了IActionFilter

现在,如果您想创建一个可用于特定操作的过滤器,那么最好继承FilterAttribute,因为它允许您像这样使用它:

public class LogActionAttribute : FilterAttribute, IActionFilter 
{ 
    public void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
        // log something about the action...
    }

    public void OnActionExecuting(ActionExecutingContext filterContext) 
    { 

    } 
}

public class HomeController : Controller
{
    [LogAction]
    public ActionResult Index()
    {
        return View();
    }
}

因此,在这种情况下,您可以使用 Attributes 选择执行过滤器的操作,而不是为每个操作执行它。


作为旁注,还有一个IResultFilter 接口,其工作方式类似于IActionFilter,它在执行结果时和执行后触发(类似IActionFilter,但用于结果而不是操作)。

这样做:

public class LogActionAttribute : ActionFilterAttribute
{

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {

    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {

    }
    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {

    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {

    }

}

等同于:

public class LogActionAttribute : FilterAttribute, IActionFilter, IResultFilter
{

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {

    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {

    }
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {

    }

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {

    }

}

...因为ActionFilterAttribute 做同样的事情:

public abstract class ActionFilterAttribute : FilterAttribute, IActionFilter, IResultFilter
{
    ...
}

【讨论】:

  • @MrChudz 你问过那么我们应该继承FilterAttribute 还是不继承?。我这样回答。现在,您问是否应该继承FilterAttribute,但它甚至不存在于您正在使用的项目中,因为它的核心,所以询问您是否应该继承框架中不存在的类是没有意义的你正在使用。你需要什么?
  • 如果只需要全局过滤器,则不需要继承任何内置过滤器类,如ActionFilterAttributeResultFilterAttribute。如果您想在您的操作中像属性一样使用它,因此过滤器仅针对特定操作执行,请让您的过滤器继承 ActionFilterAttribute 并覆盖您想要的正确方法。这就是您要寻找的答案吗?
猜你喜欢
  • 1970-01-01
  • 2017-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
相关资源
最近更新 更多