Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the OnActionExecuted method of an attribute always execute?

I've searched high and low and I can't seem to find a straight answer.

If I have a custom attribute/filter, will the OnActionExecuted method always be called? Even if there is an exception thrown?

like image 631
Patricia Avatar asked Oct 30 '09 14:10

Patricia


People also ask

Is it possible to cancel filter execution?

You can cancel filter execution in the OnActionExecuting and OnResultExecuting methods by setting the Result property to a non-null value.

How action filter works?

Action filters contain logic that is executed before and after a controller action executes. You can use an action filter, for instance, to modify the view data that a controller action returns. Result filters contain logic that is executed before and after a view result is executed.

When to use action filters in MVC?

Action filters are used to implement the logic that get executed before or after a controller action executes. Result filters contains logic that gets executed before or after a view result gets executed. E.g. if you want to change view before its get render to browser.

What is ActionFilterAttribute in MVC?

The ActionFilterAttribute is the base class for all the attribute filters. It provides the following methods to execute a specific logic after and before controller action's execution: OnActionExecuting(ActionExecutingContext filterContext): Just before the action method is called.


1 Answers

At least with MVC 5, @tvanfosson's answer is no longer correct. This may apply to earlier versions as well.

OnActionExecuted is always called and has access to the thrown exception via filterContext.Exception.

Test case with exception in an action:

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

Output:

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

Test case with exception in a filter

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

Output:

Bar.OnActionExecuting
Foo.OnActionExecuting
Foo.OnActionExecuted
Has exception: False
Exception thrown: 'System.Exception' in WebApplication1.dll
Bar.OnActionExecuted
Has exception: True
like image 69
user247702 Avatar answered Oct 21 '22 17:10

user247702