繁体   English   中英

Autofac MVC4动作过滤器注入会导致无限循环

[英]Autofac MVC4 Action Filter Injection causes infinite loop

我遇到了Action Filters和Autofac的问题。 我有一个动作过滤器,它使用依赖项来确定是否应该重定向请求。 我明确地将此过滤器应用于一组控制器操作。 重定向将指向未应用此过滤器的操作。 但是,过滤器仍会触发,我最终会无限循环。

请注意 ,下面的代码是正在进行的一些逻辑的框架。 我只是想捕捉到我遇到的问题。

在我的情况下,具有此属性的控制器是accound控制器中的内置。 即登录操作。 我已经设置了autorization过滤器以应用于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注册,那么事情就会按预期工作。 点击登录屏幕后,过滤器会触发并重定向到错误页面。

我找到了问题的问题。

我查看了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自动注册为全局过滤器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM