Пример #1
0
        protected override void DoTargetWork(Controller target, WorkContext work)
        {
            target.m_WorkContext = work;               //This also establishes Controller.App
            App.DependencyInjector.InjectInto(target); //Inject app-rooted context


            var action = GetActionName(target, work);

            object[] args;

            //1. try controller instance to resolve action
            var mi = target.FindMatchingAction(work, action, out args);

            //2. if controller did not resolve then resolve by framework (most probable case)
            if (mi == null)
            {
                mi = FindMatchingAction(target, work, action, out args);
            }


            if (mi == null)
            {
                throw new HTTPStatusException(WebConsts.STATUS_404,
                                              WebConsts.STATUS_404_DESCRIPTION,
                                              StringConsts.MVC_CONTROLLER_ACTION_UNMATCHED_HANDLER_ERROR.Args(target.GetType().FullName, action));
            }

            Security.Permission.AuthorizeAndGuardAction(App, mi, work.Session, () => work.NeedsSession());

            object result = null;

            try
            {
                try
                {
                    var handled = target.BeforeActionInvocation(work, action, mi, args, ref result);
                    if (!handled)
                    {
                        result = mi.Invoke(target, args);

                        //-----------------
                        // 20190303 DKh temp code until Wave is refactored to full async pipeline
                        //-----------------
                        if (result is Task task)
                        {
                            while (App.Active && !Disposed && !task.IsCompleted && !task.IsFaulted && !task.IsCanceled)
                            {
                                task.Wait(150);                                                                           //temporary code due to sync pipeline
                            }
                            var taskResult = task.TryGetCompletedTaskResultAsObject();
                            if (taskResult.ok)
                            {
                                result = taskResult.result;    //unwind the result
                            }
                            else if (task.IsCanceled)
                            {
                                result = null;
                            }
                            else if (task.IsFaulted)
                            {
                                throw task.Exception;
                            }
                        }
                        //-----------------


                        result = target.AfterActionInvocation(work, action, mi, args, result);
                    }
                }
                finally
                {
                    target.ActionInvocationFinally(work, action, mi, args, result);
                }
            }
            catch (Exception error)
            {
                if (error is TargetInvocationException tie)
                {
                    var cause = tie.InnerException;
                    if (cause != null)
                    {
                        error = cause;
                    }
                }

                if (error is AggregateException age)
                {
                    var cause = age.Flatten().InnerException;
                    if (cause != null)
                    {
                        error = cause;
                    }
                }
                throw MvcActionException.WrapActionBodyError(target.GetType().FullName, action, error);
            }

            if (mi.ReturnType == typeof(void))
            {
                return;
            }

            try
            {
                try
                {
                    ProcessResult(target, work, result);
                }
                catch (Exception error)
                {
                    throw MvcActionException.WrapActionResultError(target.GetType().FullName, action, result, error);
                }
            }
            finally
            {
                if (result is IDisposable)
                {
                    ((IDisposable)result).Dispose();
                }
            }
        }
Пример #2
0
        protected override void DoTargetWork(Controller target, WorkContext work)
        {
            target.m_WorkContext = work;               //This also establishes Controller.App
            App.DependencyInjector.InjectInto(target); //Inject app-rooted context


            var action = GetActionName(target, work);

            object[] args;

            //1. try controller instance to resolve action
            var mi = target.FindMatchingAction(work, action, out args);

            //2. if controller did not resolve then resolve by framework (most probable case)
            if (mi == null)
            {
                mi = FindMatchingAction(target, work, action, out args);
            }


            if (mi == null)
            {
                throw new HTTPStatusException(WebConsts.STATUS_404,
                                              WebConsts.STATUS_404_DESCRIPTION,
                                              StringConsts.MVC_CONTROLLER_ACTION_UNMATCHED_HANDLER_ERROR.Args(target.GetType().FullName, action));
            }

            Security.Permission.AuthorizeAndGuardAction(App, mi, work.Session, () => work.NeedsSession());

            object result = null;

            try
            {
                try
                {
                    var handled = target.BeforeActionInvocation(work, action, mi, args, ref result);
                    if (!handled)
                    {
                        result = mi.Invoke(target, args);
                        result = target.AfterActionInvocation(work, action, mi, args, result);
                    }
                }
                finally
                {
                    target.ActionInvocationFinally(work, action, mi, args, result);
                }
            }
            catch (Exception error)
            {
                if (error is TargetInvocationException)
                {
                    var cause = ((TargetInvocationException)error).InnerException;
                    if (cause != null)
                    {
                        error = cause;
                    }
                }
                throw MvcActionException.WrapActionBodyError(target.GetType().FullName, action, error);
            }

            if (mi.ReturnType == typeof(void))
            {
                return;
            }

            try
            {
                try
                {
                    ProcessResult(target, work, result);
                }
                catch (Exception error)
                {
                    throw MvcActionException.WrapActionResultError(target.GetType().FullName, action, result, error);
                }
            }
            finally
            {
                if (result is IDisposable)
                {
                    ((IDisposable)result).Dispose();
                }
            }
        }