internal static ActionExecutedContext BeginInvokeActionMethodFilterEndContinuation(IActionFilter filter, ActionExecutingContext preContext, Func <ActionExecutedContext> endContinuation) { bool wasError = false; ActionExecutedContext postContext = null; try { postContext = endContinuation(); } 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. postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { wasError = true; postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnActionExecuted(postContext); } return(postContext); }
internal static IAsyncResult BeginInvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, BeginInvokeCallback beginContinuation, AsyncCallback <ActionExecutedContext> endContinuation, AsyncCallback callback, object state) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { ActionExecutedContext shortCircuitContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { Result = preContext.Result }; return(new ObjectAsyncResult <ActionExecutedContext>(shortCircuitContext).ToAsyncResultWrapper(callback, state)); } try { return(AsyncResultWrapper.Wrap(callback, state, beginContinuation, ar => BeginInvokeActionMethodFilterEndContinuation(filter, preContext, () => endContinuation(ar)))); } 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. ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } return(new ObjectAsyncResult <ActionExecutedContext>(postContext).ToAsyncResultWrapper(callback, state)); } }
/// <summary> /// Execute the pre filter, the action and the post filter attribute /// </summary> /// <param name="filter">The action filter attribute</param> /// <param name="preContext">The builded executing context</param> /// <param name="continuation">Lambda expression that create the actionExecutedContext </param> /// <returns></returns> private ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func <ActionExecutedContext> continuation) { //Execute the filter filter.OnActionExecuting(preContext); //Store the executed filter listOfExecutedActionFilters.Add(filter); //if the execution process is cancelled by the pre filter if (preContext.Result != null) { return(new ActionExecutedContext(preContext.Controller, true /*cancelled*/, null /*exception*/) { Result = preContext.Result }); } bool wasError = false; ActionExecutedContext postContext = null; try { //Executing the action and initializing the postContext postContext = continuation(); } catch (Exception ex) { //An exception is caught wasError = true; postContext = new ActionExecutedContext(preContext.Controller, false /*cancelled*/, ex /*exception*/); filter.OnActionExecuted(postContext); //If the error is not handled by the filter the exception is thrown if (!postContext.ExceptionHandled) { throw; } } //Everything is well done if (!wasError && postContext.Result != null) { filter.OnActionExecuted(postContext); } return(postContext); }
public void OnActionExecuted_WhenCalled_ReturnsWithContextWhereResultIsNull() { IActionFilter sut = CreateSut(); ActionExecutedContext context = CreateActionExecutedContext(); sut.OnActionExecuted(context); Assert.That(context.Result, Is.Null); }
private static async Task ExecuteActionFilter( ActionExecutingContext context, ActionExecutionDelegate next, IActionFilter actionFilter) { actionFilter.OnActionExecuting(context); if (context.Result == null) { actionFilter.OnActionExecuted(await next()); } }
/// <summary> /// 执行活动方法筛选器 /// </summary> /// <param name="filter"></param> /// <param name="preContext"></param> /// <param name="continuation"></param> /// <returns></returns> internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func <ActionExecutedContext> continuation) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { return(new ActionExecutedContext(preContext, preContext.ActionDescriptor, true, null) { Result = preContext.Result }); } bool flag = false; ActionExecutedContext actionExecutedContext = null; try { actionExecutedContext = continuation(); } catch (ThreadAbortException) { actionExecutedContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false, null); filter.OnActionExecuted(actionExecutedContext); throw; } catch (Exception exception) { flag = true; actionExecutedContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false, exception); filter.OnActionExecuted(actionExecutedContext); if (!actionExecutedContext.ExceptionHandled) { throw; } } if (!flag) { filter.OnActionExecuted(actionExecutedContext); } return(actionExecutedContext); }
void ProcessExceptionWhenInvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Exception ex) { var postContext = new ActionExecutedContext(false /*cancelled*/, ex /*exception*/) { Controller = preContext.Controller, ActionParameters = preContext.ActionParameters, ActionMethod = _actionMethod }; filter.OnActionExecuted(postContext); //If the error is not handled by the filter the exception is thrown if (!postContext.ExceptionHandled) { throw ex; } }
/// <summary> /// Execute the pre filter, the action and the post filter attribute /// </summary> /// <param name="filter">The action filter attribute</param> /// <param name="preContext">The builded executing context</param> /// <param name="continuation">Lambda expression that create the actionExecutedContext </param> /// <returns></returns> ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Delegates.Func <ActionExecutedContext> continuation) { //Execute the filter filter.OnActionExecuting(preContext); //if the execution process is cancelled by the pre filter if (preContext.Result != null) { return(new ActionExecutedContext(true /*cancelled*/, null /*exception*/) { Controller = preContext.Controller, ActionParameters = preContext.ActionParameters, ActionMethod = _actionMethod, Result = preContext.Result }); } bool wasError = false; ActionExecutedContext postContext = null; try { //Executing the action and initializing the postContext postContext = continuation(); } catch (TargetInvocationException ex) { wasError = true; ProcessExceptionWhenInvokeActionMethodFilter(filter, preContext, ex.InnerException ?? ex); } catch (Exception ex) { //An exception is caught wasError = true; ProcessExceptionWhenInvokeActionMethodFilter(filter, preContext, ex); } //Everything is well done if (!wasError && postContext.Result != null) { filter.OnActionExecuted(postContext); } return(postContext); }
internal static IAsyncResult BeginInvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, BeginInvokeCallback beginContinuation, AsyncCallback<ActionExecutedContext> endContinuation, AsyncCallback callback, object state) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { ActionExecutedContext shortCircuitContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { Result = preContext.Result }; return new ObjectAsyncResult<ActionExecutedContext>(shortCircuitContext).ToAsyncResultWrapper(callback, state); } try { return AsyncResultWrapper.Wrap(callback, state, beginContinuation, ar => BeginInvokeActionMethodFilterEndContinuation(filter, preContext, () => endContinuation(ar))); } 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. ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } return new ObjectAsyncResult<ActionExecutedContext>(postContext).ToAsyncResultWrapper(callback, state); } }
internal Func <ActionExecutedContext> InvokeActionMethodFilterAsynchronouslyRecursive(int filterIndex) { // Performance-sensitive // For compatability, the following behavior must be maintained // The OnActionExecuting events must fire in forward order // The Begin and End events must fire // The OnActionExecuted events must fire in reverse order // Earlier filters can process the results and exceptions from the handling of later filters // This is achieved by calling recursively and moving through the filter list forwards // If there are no more filters to recurse over, create the main result if (filterIndex > _filterCount - 1) { InnerAsyncResult = _invoker.BeginInvokeActionMethod(_controllerContext, _actionDescriptor, _parameters, _asyncCallback, _asyncState); return(() => new ActionExecutedContext(_controllerContext, _actionDescriptor, canceled: false, exception: null) { Result = _invoker.EndInvokeActionMethod(InnerAsyncResult) }); } // Otherwise process the filters recursively IActionFilter filter = _filters[filterIndex]; ActionExecutingContext preContext = _preContext; filter.OnActionExecuting(preContext); if (preContext.Result != null) { ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, canceled: true, exception: null) { Result = preContext.Result }; return(() => shortCircuitedPostContext); } // There is a nested try / catch block here that contains much the same logic as the outer block. // Since an exception can occur on either side of the asynchronous invocation, we need guards on // on both sides. In the code below, the second side is represented by the nested delegate. This // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter() // method. try { // Use the filters in forward direction int nextFilterIndex = filterIndex + 1; Func <ActionExecutedContext> continuation = InvokeActionMethodFilterAsynchronouslyRecursive(nextFilterIndex); // add our own continuation, then return the new function return(() => { ActionExecutedContext postContext; bool wasError = true; try { postContext = continuation(); wasError = false; } 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. postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, canceled: false, exception: null); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, canceled: false, exception: ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnActionExecuted(postContext); } return postContext; }); } 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. ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, canceled: false, exception: null); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, canceled: false, exception: ex); filter.OnActionExecuted(postContext); if (postContext.ExceptionHandled) { return(() => postContext); } else { throw; } } }
public void OnActionExecuted_WhenContextIsNull_ThrowsArgumentNullException() { IActionFilter sut = CreateSut(); ArgumentNullException result = Assert.Throws <ArgumentNullException>(() => sut.OnActionExecuted(null)); Assert.That(result.ParamName, Is.EqualTo("context")); }
static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { return new ActionExecutedContext(preContext, true /* canceled */, null /* exception */) { Result = preContext.Result }; } bool wasError = false; ActionExecutedContext postContext = null; try { postContext = continuation(); } catch (Exception ex) { wasError = true; postContext = new ActionExecutedContext(preContext, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { if (!(postContext.Result is AsyncResult)) { filter.OnActionExecuted(postContext); } } return postContext; }
public void OnActionExecuted(ActionExecutedContext filterContext) { ActionFilter.OnActionExecuted(filterContext); }
internal static Func <ActionExecutedContext> InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func <Func <ActionExecutedContext> > nextInChain) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { Result = preContext.Result }; return(() => shortCircuitedPostContext); } // There is a nested try / catch block here that contains much the same logic as the outer block. // Since an exception can occur on either side of the asynchronous invocation, we need guards on // on both sides. In the code below, the second side is represented by the nested delegate. This // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter() // method. try { Func <ActionExecutedContext> continuation = nextInChain(); // add our own continuation, then return the new function return(() => { ActionExecutedContext postContext; bool wasError = true; try { postContext = continuation(); wasError = false; } 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. postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnActionExecuted(postContext); } return postContext; }); } 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. ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (postContext.ExceptionHandled) { return(() => postContext); } else { throw; } } }
internal static Func<ActionExecutedContext> InvokeActionMethodFilterAsynchronously(IActionFilter filter, ActionExecutingContext preContext, Func<Func<ActionExecutedContext>> nextInChain) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { ActionExecutedContext shortCircuitedPostContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { Result = preContext.Result }; return () => shortCircuitedPostContext; } // There is a nested try / catch block here that contains much the same logic as the outer block. // Since an exception can occur on either side of the asynchronous invocation, we need guards on // on both sides. In the code below, the second side is represented by the nested delegate. This // is really just a parallel of the synchronous ControllerActionInvoker.InvokeActionMethodFilter() // method. try { Func<ActionExecutedContext> continuation = nextInChain(); // add our own continuation, then return the new function return () => { ActionExecutedContext postContext; bool wasError = true; try { postContext = continuation(); wasError = false; } 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. postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnActionExecuted(postContext); } return postContext; }; } 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. ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { ActionExecutedContext postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (postContext.ExceptionHandled) { return () => postContext; } else { throw; } } }
internal static ActionExecutedContext InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func<ActionExecutedContext> continuation) { filter.OnActionExecuting(preContext); if (preContext.Result != null) { return new ActionExecutedContext(preContext, preContext.ActionDescriptor, true /* canceled */, null /* exception */) { Result = preContext.Result }; } bool wasError = false; ActionExecutedContext postContext = null; try { postContext = continuation(); } 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. postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, null /* exception */); filter.OnActionExecuted(postContext); throw; } catch (Exception ex) { wasError = true; postContext = new ActionExecutedContext(preContext, preContext.ActionDescriptor, false /* canceled */, ex); filter.OnActionExecuted(postContext); if (!postContext.ExceptionHandled) { throw; } } if (!wasError) { filter.OnActionExecuted(postContext); } return postContext; }
public void OnActionExecuted(ActionExecutedContext filterContext) { _wrappedFilter.OnActionExecuted(filterContext); }