Beispiel #1
0
        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            AddVersionHeader(httpContext);

            // Get the controller type
            string controllerName = RequestContext.RouteData.GetRequiredString("controller");

            // Instantiate the controller and call Execute
            IControllerFactory factory    = ControllerBuilder.GetControllerFactory();
            IController        controller = factory.CreateController(RequestContext, controllerName);

            if (controller == null)
            {
                throw new InvalidOperationException(
                          String.Format(
                              CultureInfo.CurrentUICulture,
                              MvcResources.ControllerBuilder_FactoryReturnedNull,
                              factory.GetType(),
                              controllerName));
            }

            BeginExecuteDelegate beginExecute;
            EndExecuteDelegate   endExecute;

            IAsyncController asyncController = controller as IAsyncController;

            if (asyncController != null)
            {
                beginExecute = asyncController.BeginExecute;
                endExecute   = asyncController.EndExecute;
            }
            else
            {
                // execute synchronous controller asynchronously
                ExecuteDelegate executeDelegate = rc => SynchronizationContext.Sync(() => controller.Execute(rc));
                beginExecute = executeDelegate.BeginInvoke;
                endExecute   = executeDelegate.EndInvoke;
            }

            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                try {
                    return(beginExecute(RequestContext, innerCallback, innerState));
                }
                catch {
                    factory.ReleaseController(controller);
                    throw;
                }
            };

            AsyncCallback endCallback = ar => {
                try {
                    endExecute(ar);
                }
                finally {
                    factory.ReleaseController(controller);
                }
            };

            return(AsyncResultWrapper.Wrap(callback, state, beginCallback, endCallback, _processRequestTag));
        }
Beispiel #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));
            }
        }
Beispiel #3
0
        protected internal virtual IAsyncResult BeginInvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary <string, object> parameters, AsyncCallback callback, object state)
        {
            BeginExecuteDelegate beginExecute;
            EndExecuteDelegate   endExecute;

            IAsyncActionDescriptor asyncDescriptor = actionDescriptor as IAsyncActionDescriptor;

            if (asyncDescriptor != null)
            {
                beginExecute = asyncDescriptor.BeginExecute;
                endExecute   = asyncDescriptor.EndExecute;
            }
            else
            {
                // execute synchronous descriptor asynchronously
                ExecuteDelegate execute = (cc, p) => SynchronizationContext.Sync(() => actionDescriptor.Execute(cc, p));
                beginExecute = execute.BeginInvoke;
                endExecute   = execute.EndInvoke;
            }

            return(AsyncResultWrapper.Wrap(callback, state,
                                           (innerCb, innerState) => beginExecute(controllerContext, parameters, innerCb, innerState),
                                           ar => {
                object returnValue = endExecute(ar);
                ActionResult result = CreateActionResult(controllerContext, actionDescriptor, returnValue);
                return result;
            }, _invokeActionMethodTag));
        }
Beispiel #4
0
        protected internal virtual IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state)
        {
            IHttpHandler requestHandler = GetHttpHandler(httpContext);

            BeginProcessRequestDelegate beginCallback;
            AsyncCallback endCallback;

            IHttpAsyncHandler asyncHandler = requestHandler as IHttpAsyncHandler;

            if (asyncHandler != null)
            {
                beginCallback = asyncHandler.BeginProcessRequest;
                endCallback   = asyncHandler.EndProcessRequest;
            }
            else
            {
                // execute synchronous IHttpHandler asynchronously
                ProcessRequestDelegate processRequestDelegate = hc => SynchronizationContext.Sync(() => requestHandler.ProcessRequest(hc));
                beginCallback = processRequestDelegate.BeginInvoke;
                endCallback   = processRequestDelegate.EndInvoke;
            }

            return(AsyncResultWrapper.Wrap(callback, state,
                                           (innerCallback, innerState) => beginCallback(HttpContext.Current, innerCallback, innerState),
                                           endCallback, _processRequestTag));
        }
        protected virtual IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state)
        {
            if (requestContext == null)
            {
                throw new ArgumentNullException("requestContext");
            }

            Initialize(requestContext);
            return(AsyncResultWrapper.Wrap(callback, state, BeginExecuteCore, EndExecuteCore, _executeTag));
        }
        protected internal virtual IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
        {
            TempData.Load(ControllerContext, TempDataProvider);

            string              actionName   = RouteData.GetRequiredString("action");
            IActionInvoker      invoker      = ActionInvoker;
            IAsyncActionInvoker asyncInvoker = invoker as IAsyncActionInvoker;

            BeginInvokeActionDelegate beginDelegate;
            EndInvokeActionDelegate   endDelegate;

            if (asyncInvoker != null)
            {
                beginDelegate = asyncInvoker.BeginInvokeAction;
                endDelegate   = asyncInvoker.EndInvokeAction;
            }
            else
            {
                // execute synchronous method asynchronously
                InvokeActionDelegate invokeDelegate = (cc, an) => AsyncManager.SynchronizationContext.Sync(() => invoker.InvokeAction(cc, an));
                beginDelegate = invokeDelegate.BeginInvoke;
                endDelegate   = invokeDelegate.EndInvoke;
            }

            return(AsyncResultWrapper.Wrap(callback, state,
                                           (innerCallback, innerState) => {
                try {
                    return beginDelegate(ControllerContext, actionName, innerCallback, innerState);
                }
                catch {
                    TempData.Save(ControllerContext, TempDataProvider);
                    throw;
                }
            },
                                           ar => {
                try {
                    bool wasActionExecuted = endDelegate(ar);
                    if (!wasActionExecuted)
                    {
                        HandleUnknownAction(actionName);
                    }
                }
                finally {
                    TempData.Save(ControllerContext, TempDataProvider);
                }
            },
                                           _executeCoreTag));
        }
Beispiel #7
0
        private static IAsyncResult CreateInvokeActionNotFoundAsyncResult(AsyncCallback callback, object state)
        {
            BeginInvokeCallback beginCallback = (innerCallback, innerState) => {
                ManualAsyncResult asyncResult = new ManualAsyncResult()
                {
                    AsyncState = innerState
                };
                asyncResult.MarkCompleted(true /* completedSynchronously */, innerCallback);
                return(asyncResult);
            };
            AsyncCallback <bool> endCallback = ar => {
                return(false);
            };

            return(AsyncResultWrapper.Wrap(callback, state, beginCallback, endCallback, _invokeActionTag));
        }
Beispiel #8
0
        protected internal virtual IAsyncResult BeginInvokeActionMethodWithFilters(ControllerContext controllerContext, IList <IActionFilter> filters, ActionDescriptor actionDescriptor, IDictionary <string, object> parameters, AsyncCallback callback, object state)
        {
            ActionExecutingContext preContext = new ActionExecutingContext(controllerContext, actionDescriptor, parameters);

            // what makes this different from the synchronous version of this method is that we have to
            // aggregate both the begin + end delegates together. overall, though, it's the same logic.
            var continuation = new {
                Begin = (BeginInvokeCallback)((innerCallback, innerState) => BeginInvokeActionMethod(controllerContext, actionDescriptor, parameters, innerCallback, innerState)),
                End   = (AsyncCallback <ActionExecutedContext>)(ar => new ActionExecutedContext(controllerContext, actionDescriptor, false /* canceled */, null /* exception */)
                {
                    Result = EndInvokeActionMethod(ar)
                })
            };

            // need to reverse the filter list because the continuations are built up backward
            var invocation = filters.Reverse().Aggregate(continuation,
                                                         (next, filter) => new {
                Begin = (BeginInvokeCallback)((innerCallback, innerState) => BeginInvokeActionMethodFilter(filter, preContext, next.Begin, next.End, innerCallback, innerState)),
                End   = (AsyncCallback <ActionExecutedContext>)EndInvokeActionMethodFilter
            });

            return(AsyncResultWrapper.Wrap(callback, state, invocation.Begin, invocation.End, _invokeActionMethodWithFiltersTag));
        }
 public IAsyncResult ToAsyncResultWrapper(AsyncCallback callback, object state)
 {
     return(AsyncResultWrapper.Wrap <T>(callback, state, BeginInvoke, EndInvoke));
 }
Beispiel #10
0
        public virtual IAsyncResult BeginInvokeAction(ControllerContext controllerContext, string actionName, AsyncCallback callback, object state)
        {
            if (controllerContext == null)
            {
                throw new ArgumentNullException("controllerContext");
            }
            if (String.IsNullOrEmpty(actionName))
            {
                throw new ArgumentException(MvcResources.Common_NullOrEmpty, "actionName");
            }

            ControllerDescriptor controllerDescriptor = GetControllerDescriptor(controllerContext);
            ActionDescriptor     actionDescriptor     = FindAction(controllerContext, controllerDescriptor, actionName);

            if (actionDescriptor == null)
            {
                // notify controller that no method matched
                return(CreateInvokeActionNotFoundAsyncResult(callback, state));
            }

            Action     continuation;
            FilterInfo filterInfo = GetFilters(controllerContext, actionDescriptor);

            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
                    continuation = () => {
                        BeginInvokeActionEndContinuation(controllerContext, filterInfo.ExceptionFilters, () => {
                            InvokeActionResult(controllerContext, authContext.Result);
                        });
                    };
                }
                else
                {
                    if (controllerContext.Controller.ValidateRequest)
                    {
                        ValidateRequest(controllerContext.HttpContext.Request);
                    }

                    IDictionary <string, object> parameters = GetParameterValues(controllerContext, actionDescriptor);

                    return(AsyncResultWrapper.Wrap(callback, state,
                                                   (innerCallback, innerState) => BeginInvokeActionMethodWithFilters(controllerContext, filterInfo.ActionFilters, actionDescriptor, parameters, innerCallback, innerState),
                                                   ar => {
                        BeginInvokeActionEndContinuation(controllerContext, filterInfo.ExceptionFilters, () => {
                            ActionExecutedContext postActionContext = EndInvokeActionMethodWithFilters(ar);
                            InvokeActionResultWithFilters(controllerContext, filterInfo.ResultFilters, postActionContext.Result);
                        });
                        return true;
                    },
                                                   _invokeActionTag));
                }
            }
            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;
                }

                continuation = () => InvokeActionResult(controllerContext, exceptionContext.Result);
            }

            return(CreateInvokeActionContinuationAsyncResult(callback, state, continuation));
        }