【问题标题】:Autofac MVC4 Action Filter Injection causes infinite loopAutofac MVC4 动作过滤器注入导致无限循环
【发布时间】:2012-08-06 18:02:46
【问题描述】:

我遇到了操作过滤器和 Autofac 的问题。我有一个操作过滤器,它使用依赖项来确定是否应该重定向请求。我仅将此过滤器显式应用于控制器操作的子集。重定向将指向未应用此过滤器的操作。但是,过滤器仍然会触发,我最终陷入了无限循环。

请注意,下面的代码是一些正在发生的逻辑的骨架。我只是想抓住我遇到的问题。

在我的情况下,具有此属性的控制器是内置帐户控制器。即登录动作。我已经设置了自动过滤器以应用于 FitlerConfig.cs 中的所有操作:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new AuthorizeAttribute());
    filters.Add(new HandleErrorAttribute());
}

我的过滤器如下所示:

public class CustomFilter : ActionFilterAttribute
{
    public SomeDependancy MyDependancy { get; set; }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (MyDependancy.ShouldRedirect)
        {
            filterContext.Result = new RedirectToRouteResult("Default",
                new RouteValueDictionary
                {
                    { "controller", "Error" }, { "action", "CustomError" }
                }
            );
        } 

        base.OnActionExecuting(filterContext);
        return;
    }
}

我的帐户管理员:

public class AccountController : Controller
{
    [AllowAnonymous]
    [CustomFilter]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }
}

错误控制器:

public class ErrorController : Controller
{
    [AllowAnonymous]
    public ActionResult CustomError()
    {
        return View("CustomError");
    }
}

最后,我的 autofac 注册:

var builder = new ContainerBuilder();

builder.Register(con => new SomeDependancy()).AsSelf().InstancePerHttpRequest();

builder.RegisterType<CustomFilter>().As<IActionFilter>().PropertiesAutowired();

// property injection on filters
builder.RegisterFilterProvider();

// Needed to allow property injection in custom action filters.
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();

builder.RegisterControllers(typeof(MvcApplication).Assembly).InjectActionInvoker();

var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

最终发生的情况是,如果我在我的 CustomFilter 中设置了一个断点,当我转到登录页面时,断点命中并发生重定向,然后断点再次命中,一次又一次。令我困惑的是,这个动作过滤器并没有应用于那个控制器或动作。

如果我注释掉依赖关系并简单地在过滤器中重定向,然后注释掉 autofac 注册,事情就会按预期工作。在点击登录屏幕时,过滤器会触发并重定向到错误页面。

【问题讨论】:

    标签: c# asp.net-mvc autofac action-filter


    【解决方案1】:

    我找到了我的问题。

    我查看了 Autofac 的 ExtensibleActionInvoker 的源代码。

    https://code.google.com/p/autofac/source/browse/src/Source/Autofac.Integration.Web.Mvc3/ExtensibleActionInvoker.cs?spec=svn94f70ab10f4d65991c600e2e80171ce4847589e6&r=94f70ab10f4d65991c600e2e80171ce4847589e6

    我在它的构造函数中读到了一条评论:

    /// The following types, if registered in the container, will be added to the
    /// filters list:
    /// <list>
    /// <item><see cref="IActionFilter"/></item>
    /// <item><see cref="IAuthorizationFilter"/></item>
    /// <item><see cref="IExceptionFilter"/></item>
    /// <item><see cref="IResultFilter"/></item>
    /// </list>
    

    为了解决我的问题,我最终得到了:

    var builder = new ContainerBuilder();
    
    builder.Register(con => new SomeDependancy()).AsSelf().InstancePerHttpRequest();
    
    // builder.RegisterType<CustomFilter>().As<IActionFilter>().PropertiesAutowired();
    
    // property injection on filters
    builder.RegisterFilterProvider();
    
    // Needed to allow property injection in custom action filters.
    builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
    
    builder.RegisterControllers(typeof(MvcApplication).Assembly).InjectActionInvoker();
    
    var container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    

    事实证明,我不需要注册我的 CustomFilter。这样做似乎会导致 ExtensibleActionInvoker 自动注册为全局过滤器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-04
      • 2016-05-07
      相关资源
      最近更新 更多