2009-05-05 3 views
1

Похоже, я о том, чтобы сделать что-то снова странно ...Какое перенаправление имеет приоритет - тот, что находится в действии контроллера или в OnActionExecuted ActionFilter?

Ситуация:

public ExperimentAttribute 
{ 
    public override void OnActionExecuted (ActionExecutingContext filterContext) 
    { 
     filterContext.Result = 
        new RedirectToRouteResult (
         new RouteValueDictionary (new { Action = "Action2", Controller = "Experiment" })); 
    } 
} 

public ExperimentController 
{ 
    [Experiment] 
    public ActionResult ExperimentEntryPoint() 
    { 
     RedirectToAction ("Action1", "Experiment"); 
    } 

    public ActionResult Action1() 
    { 
     /* ... */ 
    } 

    public ActionResult Action2() 
    { 
     /* ... */ 
    } 
} 

Так, что перенаправление будет происходить? Тот, который работает в контроллере, тот, который находится в ActionFilter или, возможно, и тот, и другой?

ответ

0

Они не могут оба произойти, поскольку оба они возвращают перенаправление HTTP 302.

Атрибут выполнит перенаправление, так как это последнее, что должно произойти до того, как результат будет отправлен клиенту. И OnActionExecuting, и OnActionExecuted будут выполняться поверх результата действия контроллера.

+0

Ура, я удалю свой ответ сейчас Мастермонд завершил свой эксперимент. Кажется, это странный случай. –

+0

Согласен, это логично не имеет смысла. –

1

Итак, я только что провел эксперимент, который подтвердил, что я ожидал.

ЭкспериментEntryPoint возвращает ActionResult, а именно перенаправление на Action1.

OnActionExecuted перезаписывает результат до того, как остальная часть структуры обработает его. Когда дело доходит до него, он видит перенаправление на команду Action2.

Nice и ясно.

1

Я не могу придумать причину (YET!) Я могу подумать о нескольких причинах, по которым вы можете сделать это в OnActionExecuting(), перед выполнением кода метода Action) для изменения ActionResult с помощью filterContext.Result в методе OnActionExecuting(), но это определенно разрешено.

Порядок исполнения является:

  • OnActionExecuting()
  • Вашего Действия код метода в контроллере
  • OnActionExecuted()
  • OnResultExecuting()
  • Независимо от назначенного ActionResult.ExecuteResult() возвращает (отображает представление, json, содержимое и т. д.)
  • OnResultExecuted()

Как показал ваш эксперимент, вы можете изменить filterContext.Result как в OnActionExecuted(), так и OnActionExecuting(). Поскольку OnActionExecuted() вызывается после вашего кода контроллера (например: return RedirectToAction()), то, что он устанавливает, поскольку ActionResult имеет приоритет.

Я нашел достойное освещение ActionFilters в книге Стивена Сандерсона «Про ASP.NET MVC framework». [1] [2]

[1] http://books.google.com/books?id=Xb3a1xTSfZgC (содержание на ActionFilters не доступна в Google Book Preview)

[2] http://blog.codeville.net/2009/04/29/now-published-pro-aspnet-mvc-framework-apress/