Всегда ли выполняется метод OnActionExecuted атрибута? - PullRequest
12 голосов
/ 30 октября 2009

Я искал высоко и низко, и я не могу найти прямой ответ.

Если у меня есть собственный атрибут / фильтр, всегда ли будет вызываться метод OnActionExecuted? Даже если есть исключение?

1 Ответ

7 голосов
/ 05 июля 2016

По крайней мере, с MVC 5 ответ @ tvanfosson больше не является правильным. Это может относиться и к более ранним версиям.

OnActionExecuted всегда вызывается и имеет доступ к выброшенному исключению через filterContext.Exception.

Тестовый пример с исключением в действии:

public class HomeController
    : Controller
{
    public ActionResult Index()
    {
        throw new Exception("Index");
    }
}

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new Foo());
        filters.Add(new Bar());
    }
}

public class Foo
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

public class Bar
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

Выход:

Bar.OnActionExecuting
Foo.OnActionExecuting
Exception thrown: 'System.Exception' in WebApplication1.dll
Foo.OnActionExecuted
Has exception: True
Bar.OnActionExecuted
Has exception: True

Тестовый случай с исключением в фильтре

public class HomeController
    : Controller
{
    public ActionResult Index()
    {
        return new HttpStatusCodeResult(200);
    }
}

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new Foo());
        filters.Add(new Bar());
    }
}

public class Foo
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Foo)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        throw new Exception("Foo");
        base.OnActionExecuted(filterContext);
    }
}

public class Bar
    : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuting)}");
        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine($"{nameof(Bar)}.{nameof(OnActionExecuted)}");
        Debug.WriteLine($"Has exception: {filterContext.Exception != null}");
        base.OnActionExecuted(filterContext);
    }
}

Выход:

Bar.OnActionExecuting
Foo.OnActionExecuting
Foo.OnActionExecuted
Has exception: False
Exception thrown: 'System.Exception' in WebApplication1.dll
Bar.OnActionExecuted
Has exception: True
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...