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(); } } }
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(); } } }