public void OnActionExecuting_Should_Update_Result_When_Model_Is_Invalid()
        {
            var actionContext = new ActionContext
            {
                HttpContext      = new DefaultHttpContext(),
                RouteData        = new RouteData(),
                ActionDescriptor = new ActionDescriptor()
            };
            var context = new ActionExecutingContext(actionContext, Substitute.For <IList <IFilterMetadata> >(), Substitute.For <IDictionary <string, object> >(), null);

            var field   = "field";
            var message = "validation message";

            actionContext.ModelState.AddModelError(field, message);
            var errors = new ModelErrorCollection();

            errors.Add(message);
            var data = new [] { new { Key = field, Errors = errors } };

            _filter.OnActionExecuting(context);

            context.Result.Should().BeAssignableTo <ObjectResult>();
            context.Result.As <ObjectResult>().StatusCode.Should().Be(StatusCodes.Status400BadRequest);
            context.Result.As <ObjectResult>().Value.Should().BeAssignableTo <ApiResponse>();
            context.Result.As <ObjectResult>().Value.As <ApiResponse>().Success.Should().BeFalse();
            context.Result.As <ObjectResult>().Value.As <ApiResponse>().Message.Should().Be("Invalid request format.");
            context.Result.As <ObjectResult>().Value.As <ApiResponse>().Data.Should().BeEquivalentTo(data);
        }
Exemplo n.º 2
0
        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));
            }
        }
Exemplo n.º 3
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndNonExpiredRefreshableTokenWasPresent_AssertAuthorizeAsyncWasNotCalledOnTokenHelperFactory()
        {
            IActionFilter sut = CreateSut();

            ActionExecutingContext context = CreateActionExecutingContext();

            sut.OnActionExecuting(context);

            _tokenHelperFactoryMock.Verify(m => m.AuthorizeAsync(It.IsAny <TokenType>(), It.IsAny <HttpContext>(), It.IsAny <string>()), Times.Never());
        }
Exemplo n.º 4
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndNonExpiredRefreshableTokenWasPresent_ReturnsWithContextWhereResultIsNull()
        {
            IActionFilter sut = CreateSut();

            ActionExecutingContext context = CreateActionExecutingContext();

            sut.OnActionExecuting(context);

            Assert.That(context.Result, Is.Null);
        }
Exemplo n.º 5
0
        protected IActionResult GetActionResult(IActionFilter filter, ModelStateDictionary modelState, IDictionary <string, object> actionArguments)
        {
            var actionContext          = new ActionContext(new DefaultHttpContext(), new RouteData(), new ActionDescriptor(), modelState);
            var mockFilters            = new Mock <IList <IFilterMetadata> >();
            var actionExecutingContext = new ActionExecutingContext(actionContext, mockFilters.Object, actionArguments, null);

            filter.OnActionExecuting(actionExecutingContext);

            return(actionExecutingContext.Result);
        }
Exemplo n.º 6
0
        public void OnActionExecuting_WhenActionNotDecoratedWithAcquireTokenAttribute_ReturnsWithContextWhereResultIsNull()
        {
            IActionFilter sut = CreateSut();

            ActionDescriptor       actionDescriptor = CreateActionDescriptor(false);
            ActionExecutingContext context          = CreateActionExecutingContext(actionDescriptor);

            sut.OnActionExecuting(context);

            Assert.That(context.Result, Is.Null);
        }
Exemplo n.º 7
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndRefreshableTokenWasNotPresent_ReturnsWithContextWhereResultIsActionResultFromAuthorizeAsync()
        {
            IActionResult authorizeActionResult = new Mock <IActionResult>().Object;
            IActionFilter sut = CreateSut(hasRefreshableToken: false, authorizeActionResult: authorizeActionResult);

            ActionExecutingContext context = CreateActionExecutingContext();

            sut.OnActionExecuting(context);

            Assert.That(context.Result, Is.EqualTo(authorizeActionResult));
        }
Exemplo n.º 8
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndRefreshableTokenWasPresent_AssertHasExpiredWasCalledOnRefreshableToken()
        {
            Mock <IRefreshableToken> refreshableTokenMock = _fixture.BuildRefreshableTokenMock();
            IActionFilter            sut = CreateSut(refreshableToken: refreshableTokenMock.Object);

            ActionExecutingContext context = CreateActionExecutingContext();

            sut.OnActionExecuting(context);

            refreshableTokenMock.Verify(m => m.HasExpired, Times.Once);
        }
Exemplo n.º 9
0
        public void OnActionExecuting_WhenActionNotDecoratedWithAcquireTokenAttribute_AssertRefreshTokenAsyncWasNotCalledOnTokenHelperFactory()
        {
            IActionFilter sut = CreateSut();

            ActionDescriptor       actionDescriptor = CreateActionDescriptor(false);
            ActionExecutingContext context          = CreateActionExecutingContext(actionDescriptor);

            sut.OnActionExecuting(context);

            _tokenHelperFactoryMock.Verify(m => m.RefreshTokenAsync(It.IsAny <TokenType>(), It.IsAny <HttpContext>(), It.IsAny <string>()), Times.Never());
        }
Exemplo n.º 10
0
 private static async Task ExecuteActionFilter(
     ActionExecutingContext context,
     ActionExecutionDelegate next,
     IActionFilter actionFilter)
 {
     actionFilter.OnActionExecuting(context);
     if (context.Result == null)
     {
         actionFilter.OnActionExecuted(await next());
     }
 }
Exemplo n.º 11
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndExpiredRefreshableTokenWasPresent_ReturnsWithContextWhereResultIsActionResultFromRefreshTokenAsync()
        {
            IRefreshableToken refreshableToken         = _fixture.BuildRefreshableTokenMock(hasExpired: true).Object;
            IActionResult     refreshTokenActionResult = new Mock <IActionResult>().Object;
            IActionFilter     sut = CreateSut(refreshableToken: refreshableToken, refreshTokenActionResult: refreshTokenActionResult);

            ActionExecutingContext context = CreateActionExecutingContext();

            sut.OnActionExecuting(context);

            Assert.That(context.Result, Is.EqualTo(refreshTokenActionResult));
        }
Exemplo n.º 12
0
        public void OnActionExecuting_WhenActionNotDecoratedWithAcquireTokenAttribute_AssertHasExpiredWasNotCalledOnRefreshableToken()
        {
            Mock <IRefreshableToken> refreshableTokenMock = _fixture.BuildRefreshableTokenMock();
            IActionFilter            sut = CreateSut(refreshableToken: refreshableTokenMock.Object);

            ActionDescriptor       actionDescriptor = CreateActionDescriptor(false);
            ActionExecutingContext context          = CreateActionExecutingContext(actionDescriptor);

            sut.OnActionExecuting(context);

            refreshableTokenMock.Verify(m => m.HasExpired, Times.Never);
        }
Exemplo n.º 13
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttribute_AssertGetTokenAsyncWasCalledOnTokenHelperFactoryForRefreshableToken()
        {
            IActionFilter sut = CreateSut();

            HttpContext            httpContext = CreateHttpContext();
            ActionExecutingContext context     = CreateActionExecutingContext(httpContext: httpContext);

            sut.OnActionExecuting(context);

            _tokenHelperFactoryMock.Verify(m => m.GetTokenAsync <IRefreshableToken>(
                                               It.Is <TokenType>(value => value == TokenType.MicrosoftGraphToken),
                                               It.Is <HttpContext>(value => value == httpContext)),
                                           Times.Once);
        }
Exemplo n.º 14
0
        public void OnActionExecuting_WhenActionDecoratedWithAcquireTokenAttributeAndRefreshableTokenWasNotPresent_AssertAuthorizeAsyncWasCalledOnTokenHelperFactory()
        {
            IActionFilter sut = CreateSut(hasRefreshableToken: false);

            string                 pathBase    = $"/{_fixture.Create<string>()}";
            string                 path        = $"/{_fixture.Create<string>()}";
            HttpContext            httpContext = CreateHttpContext(pathBase, path);
            ActionExecutingContext context     = CreateActionExecutingContext(httpContext: httpContext);

            sut.OnActionExecuting(context);

            _tokenHelperFactoryMock.Verify(m => m.AuthorizeAsync(
                                               It.Is <TokenType>(value => value == TokenType.MicrosoftGraphToken),
                                               It.Is <HttpContext>(value => value == httpContext),
                                               It.Is <string>(value => string.CompareOrdinal(value, $"http://localhost{pathBase}{path}") == 0)),
                                           Times.Once());
        }
Exemplo n.º 15
0
        /// <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);
        }
Exemplo n.º 16
0
        /// <summary>
        /// 取得Action執行結果(包含Filter)
        /// </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)
        {
            //執行Action 過濾器
            filter.OnActionExecuting(preContext);
            //如果有Result 直接返回
            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 */);
                //執行Action後 過濾器
                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);
        }
Exemplo n.º 17
0
        /// <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);
        }
Exemplo n.º 18
0
        /// <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);
        }
        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;
        }
Exemplo n.º 20
0
        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;
                }
            }
        }
Exemplo n.º 21
0
 public void OnActionExecuting(ActionExecutingContext filterContext)
 {
     ActionFilter.OnActionExecuting(filterContext);
 }
Exemplo n.º 22
0
        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;
        }
Exemplo n.º 23
0
        public void OnActionExecuting_WhenContextIsNull_ThrowsArgumentNullException()
        {
            IActionFilter sut = CreateSut();

            ArgumentNullException result = Assert.Throws <ArgumentNullException>(() => sut.OnActionExecuting(null));

            Assert.That(result.ParamName, Is.EqualTo("context"));
        }
        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;
                }
            }
        }
Exemplo n.º 25
0
            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;
                    }
                }
            }
        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);
            }
        }
Exemplo n.º 27
0
 public void OnActionExecuting(ActionExecutingContext filterContext)
 {
     _wrappedFilter.OnActionExecuting(filterContext);
 }