Вызов OnActionExecuting функции FilterAttribute перед OnActionExecuting BaseController - PullRequest
6 голосов
/ 19 мая 2009

У меня есть BaseController, в который я помещаю некоторые данные в коллекцию ViewData путем переопределения OnActionExecuting.

Теперь у меня есть действие в ChildController, которому не нужны эти данные просмотра.

Для этой цели я создал DontPopulateViewData ActionFilterAttribute, который устанавливает значение bool для BaseController, которое не позволяет BaseController заполнять данные представления.

Проблема: метод ActionFilters OnActionExecuting вызывается после того, как в BaseController, а не до.

Будут ли всегда вызываться ActionFilters перед переопределением OnActionExecuting в базовых контроллерах, и есть ли способ обойти это?

Ответы [ 2 ]

15 голосов
/ 20 мая 2009

В дополнение к тому, что написал и предложил Марван Ауида (используя ActionFilter в базовом классе), я не думаю, что вы сможете создать ActionFilter, который выполняется до перегрузки OnActionExecuting () в базовом классе. , Следующий код:

 [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>");
     }
 }

производит этот вывод:

MyBaseController::Execute()
MyBaseController::OnActionExecuting()
MyActionFilter_Derived::OnActionExecuting()
MyActionFilter_Base::OnActionExecuting()
MyTestController::Index()
MyActionFilter_Base::OnActionExecuted()
MyActionFilter_Derived::OnActionExecuted()
MyBaseController::OnActionExecuted()
0 голосов
/ 19 мая 2009

Класс ActionFilterAttribute имеет свойство под названием «Порядок», которое можно использовать для задания порядка, в котором выполняются фильтры действий.
В вашем случае вы должны установить порядок атрибута фильтра в BaseController равным 2, а атрибут фильтра в DerivedController равным 1:

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

  public ActionResult MyAction() {

  }

}

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

  public ActionResult AnotherAction() {

  }

}

Прочтите это для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/dd381609.aspx

Примечание: я не проверял это.

...