我一直在对动作过滤器进行一些研究,并想知道是否有办法以编程方式将它们添加到控制器中?
为了给出一些上下文,我想在web.config中配置日志记录时添加日志记录过滤器,否则我不希望过滤器存在于每个操作方法的执行链中。
我感谢我可以检查实际的过滤器代码本身,看看是否已启用日志记录,但不希望这样做。
非常感谢!
答案 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
希望这有帮助。