Chamando OnActionExecuting de FilterAttribute antes OnActionExecuting de BaseController

votos
6

Eu tenho um BaseControllerem que eu coloquei em alguns dados na ViewDatacoleção, substituindo OnActionExecuting.

Agora eu tenho uma ação em um ChildControllerque não precisa que os dados vista.

Para esse efeito, eu criei um DontPopulateViewDataActionFilterAttribute que define um bool sobre o BaseControllerque impede o BaseControllerde preencher o viewdata.

Problema: o ActionFilters OnActionExecutingmétodo é chamado após aquele em BaseControllere não antes.

Vai ActionFilters sempre ser chamado antes substituído OnActionExecutingem controladores de base e se existe uma maneira de contornar este problema?

Publicado 19/05/2009 em 14:53
fonte usuário
Em outras línguas...                            


2 respostas

votos
15

Além do que Marwan Aouida postado e sugeriu (usando um ActionFilter na classe base), eu não acho que você vai ser capaz de criar um ActionFilter que executa antes da sobrecarga OnActionExecuting () na classe base. O código a seguir:

 [MyActionFilter(Name = "Base", Order = 2)]
 public class MyBaseController : Controller
 {
     protected override void OnActionExecuting(ActionExecutingContext filterContext)
     {
        Response.Write("MyBaseController::OnActionExecuting()<br>");
        base.OnActionExecuting(filterContext);
     }

     protected override void Execute(System.Web.Routing.RequestContext requestContext)
     {
        requestContext.HttpContext.Response.Write("MyBaseController::Execute()<br>");
        base.Execute(requestContext);
     }

    protected override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Response.Write("MyBaseController::OnActionExecuted()<br>");
        base.OnActionExecuted(filterContext);
    }
 }

 public class MyActionFilter : ActionFilterAttribute
 {
    public string Name;

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.Write("MyActionFilter_" + Name + "::OnActionExecuted()<br>");
        base.OnActionExecuted(filterContext);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Write("MyActionFilter_" + Name + "::OnActionExecuting()<br>");
        base.OnActionExecuting(filterContext);
    }
 }

 public class MyTestController : MyBaseController
 {
     [MyActionFilter(Name = "Derived", Order = 1)]
     public void Index()
     {
        Response.Write("MyTestController::Index()<br>");
     }
 }

produz esta saída:

MyBaseController::Execute()
MyBaseController::OnActionExecuting()
MyActionFilter_Derived::OnActionExecuting()
MyActionFilter_Base::OnActionExecuting()
MyTestController::Index()
MyActionFilter_Base::OnActionExecuted()
MyActionFilter_Derived::OnActionExecuted()
MyBaseController::OnActionExecuted()
Respondeu 19/05/2009 em 21:42
fonte usuário

votos
0

A classe ActionFilterAttribute tem uma propriedade chamada "Ordem", que você pode usar para definir a ordem em que os filtros de ação são executados.
No seu caso, você tem que definir a ordem do atributo de filtro na BaseController a 2 e o atributo de filtro na DerivedController a 1:

[MyFilter(Order=2)]
public class BaseController:Controller
{

  public ActionResult MyAction() {

  }

}

[MySecondFilter(Order=1)]
public class DerivedController:BaseController
{

  public ActionResult AnotherAction() {

  }

}

Leia este para mais informações sobre: http://msdn.microsoft.com/en-us/library/dd381609.aspx

Nota: Eu não testei isso.

Respondeu 19/05/2009 em 17:32
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more