views:

125

answers:

1

Hi everyone,

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 sub always be called? Even if there is an exception thrown?

Thanks

+2  A: 

No. OnActionExecuted is only executed when the action actually completes. The ControllerActionInvoker class wraps the invocation of the action in a try/catch block but the OnActionExecuted method is called within the try portion of the block. If an exception is throw when the action is executing, it won't complete the try block, but will instead execute the code in one of the catch blocks.

See the code at http://aspnet.codeplex.com/SourceControl/changeset/view/23011#266452. Relevant snippet below:

   try {
        AuthorizationContext authContext = InvokeAuthorizationFilters(controllerContext, filterInfo.AuthorizationFilters, actionDescriptor);
        if (authContext.Result != null) {
            // the auth filter signaled that we should let it short-circuit the request
            InvokeActionResult(controllerContext, authContext.Result);
        }
        else {
            if (controllerContext.Controller.ValidateRequest) {
                ValidateRequest(controllerContext.HttpContext.Request);
            }

            IDictionary<string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);
            ActionExecutedContext postActionContext = InvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters);
            InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
        }
    }
    catch (ThreadAbortException) {
        // This type of exception occurs as a result of Response.Redirect(), but we special-case so that
        // the filters don't see this as an error.
        throw;
    }
    catch (Exception ex) {
        // something blew up, so execute the exception filters
        ExceptionContext exceptionContext = InvokeExceptionFilters(controllerContext, filterInfo.ExceptionFilters, ex);
        if (!exceptionContext.ExceptionHandled) {
            throw;
        }
        InvokeActionResult(controllerContext, exceptionContext.Result);
    }
tvanfosson
That's a great explanation! Thanks!
Patricia