ASP.NET MVC - 以编程方式添加动作过滤器

时间:2009-01-24 14:05:43

标签: .net asp.net-mvc

我一直在对动作过滤器进行一些研究,并想知道是否有办法以编程方式将它们添加到控制器中?

为了给出一些上下文,我想在web.config中配置日志记录时添加日志记录过滤器,否则我不希望过滤器存在于每个操作方法的执行链中。

我感谢我可以检查实际的过滤器代码本身,看看是否已启用日志记录,但不希望这样做。

非常感谢!

5 个答案:

答案 0 :(得分:1)

    [LogRequest]
    [PermissionRequired(Permits.View_users, Permits.Edit_users)]
    public ActionResult Edit(int id, .....)
            {
             ...
            }

    public class PermissionRequired : ActionFilterAttribute, IActionFilter
{
    private readonly PermissionsList permits;

    public PermissionRequired(params Permits[] perm)
    {
        permits = new PermissionsList(perm);
    }

    #region IActionFilter Members

    void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
    {
        ...
        IEnumerable<int> intersection = (from up in User.CurrentUser.UserPermission
                                         select up.PermissionID).ToList().Intersect(permits.Cast<int>());
        if (intersection.Count() != permits.Count)
        {
            filterContext.Result = null;
            HttpContext.Current.Response.Redirect("/Error/PermissionsRequired.htm");
        }
    }

    #endregion
}

答案 1 :(得分:1)

更好的解决方案是使用 null object pattern

您的过滤器将正常记录(其作业是记录,而不是决定如何记录或记录什么,但是默认情况下,实际记录器将是一个什么都不做的实现。如果已配置,则记录器实例将是按配置记录的实现。

一个简单的工厂可以决定将哪个记录器实现传递给过滤器,或者可以配置任何IOC容器来处理它。

答案 2 :(得分:0)

我从来没有以编程方式向方法添加属性,因为它看起来像一个低效的噩梦,我总是找到一个更好的选择。

你需要在某个地方进行检查,虽然我同意属性代码可能不适合它,但它并不是特别糟糕。如果你真的不想这样做,那么你可以抽象出日志代码,这样它只需要启用的条目类型,然后由你自己想要放置多少架构。

答案 3 :(得分:0)

您可以查看创建自己的ActionInvoker实现,它是处理调用过滤器和操作方法的类。话虽如此,我认为这不是一个好的解决方案。它违反了关注点的分离。最好让您的日志记录操作过滤器确定是否应该进行日志记录。

答案 4 :(得分:0)

我一直在寻找新的Oxite代码(最后一个版本由于大量的评论家而遭受了重大的重构)并且他们做了一些有趣的事情。 他们创建自己的ActionFilterRepository来保存不同的过滤器(IActionFilters,IAuthorizationFilters等)。在自定义ControllerActionInvoker中,GetFilters方法被覆盖,并将存储库中的过滤器添加到当前集合中。这样,它们就有一组应用于每个动作和控制器的全局过滤器。

您可以在此处查看自定义调用程序代码: OxiteControllerActionInvoker.cs

这里有一个示例过滤器: LocalizationActionFilter.cs

希望这有帮助。