private IViewComponentResult InvokeSyncCore(ViewComponentContext context)
        {
            var component = CreateComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                var method    = context.ViewComponentDescriptor.MethodInfo;
                var arguments = ControllerActionExecutor.PrepareArguments(
                    context.Arguments,
                    method.GetParameters());

                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context, arguments);

                var    startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0;
                object result;
                try
                {
                    result = method.Invoke(component, arguments);
                }
                catch (TargetInvocationException ex)
                {
                    // Preserve callstack of any user-thrown exceptions.
                    var exceptionInfo = ExceptionDispatchInfo.Capture(ex.InnerException);
                    exceptionInfo.Throw();
                    return(null); // Unreachable
                }

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTimestamp, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                return(viewComponentResult);
            }
        }
예제 #2
0
        private IViewComponentResult InvokeSyncCore(ObjectMethodExecutor executor, ViewComponentContext context)
        {
            var component = _viewComponentFactory.CreateViewComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                var arguments = ControllerActionExecutor.PrepareArguments(
                    context.Arguments,
                    executor);

                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context, arguments);

                var    startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0;
                object result;

                try
                {
                    result = executor.Execute(component, arguments);
                }
                finally
                {
                    _viewComponentFactory.ReleaseViewComponent(context, component);
                }

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTimestamp, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                _viewComponentFactory.ReleaseViewComponent(context, component);

                return(viewComponentResult);
            }
        }
예제 #3
0
        private async Task <IViewComponentResult> InvokeAsyncCore(ViewComponentContext context)
        {
            var component = _viewComponentFactory.CreateViewComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                var method    = context.ViewComponentDescriptor.MethodInfo;
                var arguments = ControllerActionExecutor.PrepareArguments(context.Arguments, method.GetParameters());

                var methodExecutor = _viewComponentInvokerCache.GetViewComponentMethodExecutor(context);

                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context, arguments);

                var startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0;
                var result         = await ControllerActionExecutor.ExecuteAsync(methodExecutor, component, arguments);

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTimestamp, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                _viewComponentFactory.ReleaseViewComponent(context, component);

                return(viewComponentResult);
            }
        }
예제 #4
0
        public async Task AsyncAction_WithCustomTaskReturnTypeThrows()
        {
            // Arrange
            var inputParam1      = 1;
            var inputParam2      = "Second Parameter";
            var actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            // If it is an unrecognized derived type we throw an InvalidOperationException.
            var methodWithCutomTaskReturnType = new MethodWithCustomTaskReturnType(_controller.TaskActionWithCustomTaskReturnType);

            var expectedException = string.Format(
                CultureInfo.CurrentCulture,
                "The method 'TaskActionWithCustomTaskReturnType' on type '{0}' returned a Task instance even though it is not an asynchronous method.",
                typeof(TestController));

            // Act & Assert
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(
                () => ControllerActionExecutor.ExecuteAsync(
                    methodWithCutomTaskReturnType.GetMethodInfo(),
                    _controller,
                    actionParameters));

            Assert.Equal(expectedException, ex.Message);
        }
예제 #5
0
        public async Task AsyncAction_ReturningUnwrappedTaskThrows()
        {
            // Arrange
            var inputParam1      = 1;
            var inputParam2      = "Second Parameter";
            var actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithUnwrappedTask = new MethodWithTaskReturnType(_controller.UnwrappedTask);

            var expectedException = string.Format(
                CultureInfo.CurrentCulture,
                "The method 'UnwrappedTask' on type '{0}' returned an instance of '{1}'. " +
                "Make sure to call Unwrap on the returned value to avoid unobserved faulted Task.",
                typeof(TestController),
                typeof(Task <Task>).FullName);

            // Act & Assert
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(
                () => ControllerActionExecutor.ExecuteAsync(
                    methodWithUnwrappedTask.GetMethodInfo(),
                    _controller,
                    actionParameters));

            Assert.Equal(expectedException, ex.Message);
        }
        private async Task <IViewComponentResult> InvokeAsyncCore(
            MethodInfo method,
            ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context);

                var startTime = Environment.TickCount;
                var result    = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);

                var viewComponentResult = CoerceToViewComponentResult(result);
                _logger.ViewComponentExecuted(context, startTime, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                return(viewComponentResult);
            }
        }
예제 #7
0
        public async Task InvalidParameterValueThrows()
        {
            // Arrange
            var inputParam2 = "Second Parameter";

            var actionParameters = new Dictionary <string, object> {
                { "i", "Some Invalid Value" }, { "s", inputParam2 }
            };
            var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskValueTypeAction);
            var message = TestPlatformHelper.IsMono ? "Object type {0} cannot be converted to target type: {1}" :
                          "Object of type '{0}' cannot be converted to type '{1}'.";
            var expectedException = string.Format(
                CultureInfo.CurrentCulture,
                message,
                typeof(string),
                typeof(int));

            // Act & Assert
            // If it is an unrecognized derived type we throw an InvalidOperationException.
            var ex = await Assert.ThrowsAsync <ArgumentException>(
                () => ControllerActionExecutor.ExecuteAsync(
                    methodWithTaskOfIntReturnType.GetMethodInfo(),
                    _controller,
                    actionParameters));

            Assert.Equal(expectedException, ex.Message);
        }
예제 #8
0
        public async Task AsyncAction_WithVoidReturnType()
        {
            var methodWithVoidReturnType = new MethodWithVoidReturnType(TestController.VoidAction);
            var result = await ControllerActionExecutor.ExecuteAsync(
                methodWithVoidReturnType.GetMethodInfo(),
                null,
                (IDictionary <string, object>) null);

            Assert.Same(null, result);
        }
예제 #9
0
        private async Task <IViewComponentResult> InvokeAsyncCore(
            [NotNull] MethodInfo method,
            [NotNull] ViewComponentContext context)
        {
            var component = CreateComponent(context);

            var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);

            return(CoerceToViewComponentResult(result));
        }
예제 #10
0
        private async Task <IWebSocketActionResult> InvokeActionMethodAsync(ObjectMethodExecutor executor, object controller, IDictionary <string, object> parameters)
        {
            // Order the parameters used to invoke the action
            var orderedParameters = ControllerActionExecutor.PrepareArguments(parameters, executor);

            // Execute the action
            var resultAsObject = executor.Execute(controller, orderedParameters);

            // If the result is not of type IWebSocketActionResult, create a WebSocketObjectResult with the result
            return(resultAsObject as IWebSocketActionResult ?? new WebSocketObjectResult(resultAsObject));
        }
예제 #11
0
        public async Task SyncAction()
        {
            string inputString = "hello";
            var    syncMethod  = new SyncMethod(_controller.Echo);
            var    result      = await ControllerActionExecutor.ExecuteAsync(
                syncMethod.GetMethodInfo(),
                _controller,
                new Dictionary <string, object>() { { "input", inputString } });

            Assert.Equal(inputString, result);
        }
예제 #12
0
        /// <summary>
        /// Invokes an asynchronous method.
        /// </summary>
        /// <param name="method">The method to invoke.</param>
        /// <param name="context">The widget context.</param>
        /// <returns>The widget result.</returns>
        private async Task <IWidgetResult> InvokeAsyncCore(MethodInfo method, WidgetContext context)
        {
            var widget = CreateWidget(context);

            var arguments = await GetArgumentsAsync(context, method, context.Values);

            var result = await ControllerActionExecutor.ExecuteAsync(method, widget, arguments);

            var widgetResult = CoerceToWidgetResult(result);

            return(widgetResult);
        }
예제 #13
0
 public async Task SyncAction_WithException()
 {
     string inputString = "hello";
     var    syncMethod  = new SyncMethod(_controller.EchoWithException);
     await Assert.ThrowsAsync <NotImplementedException>(
         () => ControllerActionExecutor.ExecuteAsync(
             syncMethod.GetMethodInfo(),
             _controller,
             new Dictionary <string, object>()
     {
         { "input", inputString }
     }));
 }
예제 #14
0
        public async Task ExecuteAsync_WithArgumentDictionary_DefaultParameterValueUsed()
        {
            // Arrange
            var syncMethod = new SyncMethod(_controller.EchoWithDefaultValueAndAttribute);

            // Act
            var result = await ControllerActionExecutor.ExecuteAsync(
                syncMethod.GetMethodInfo(),
                _controller,
                new Dictionary <string, object>());

            // Assert
            Assert.Equal("world", result);
        }
예제 #15
0
        public async Task AsyncAction_WithoutAsyncThrows()
        {
            int    inputParam1      = 1;
            string inputParam2      = "Second Parameter";
            var    actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskActionWithExceptionWithoutAsync);
            await Assert.ThrowsAsync <NotImplementedException>(
                () => ControllerActionExecutor.ExecuteAsync(methodWithTaskOfIntReturnType.GetMethodInfo(),
                                                            _controller,
                                                            actionParameters));
        }
예제 #16
0
        public async Task ExecuteAsync_WithArgumentDictionary_AnyValue_HasPrecedenceOverDefaults()
        {
            // Arrange
            var syncMethod = new SyncMethod(_controller.EchoWithDefaultValueAndAttribute);

            // Act
            var result = await ControllerActionExecutor.ExecuteAsync(
                syncMethod.GetMethodInfo(),
                _controller,
                new Dictionary <string, object>() { { "input", null } });

            // Assert
            Assert.Null(result);
        }
예제 #17
0
        public async Task ExecuteAsync_WithArgumentArray_DefaultValueAttributeIgnored()
        {
            // Arrange
            var syncMethod = new SyncMethod(_controller.EchoWithDefaultValue);

            // Act
            var result = await ControllerActionExecutor.ExecuteAsync(
                syncMethod.GetMethodInfo(),
                _controller,
                new object[] { null, });

            // Assert
            Assert.Null(result);
        }
        protected override async Task <IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext)
        {
            var actionMethodInfo  = _descriptor.MethodInfo;
            var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(
                actionMethodInfo,
                actionExecutingContext.Controller,
                actionExecutingContext.ActionArguments);

            var actionResult = CreateActionResult(
                actionMethodInfo.ReturnType,
                actionReturnValue);

            return(actionResult);
        }
예제 #19
0
        public async Task AsyncAction_TaskOfTaskOfValueReturnType()
        {
            int    inputParam1      = 1;
            string inputParam2      = "Second Parameter";
            var    actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithTaskOfTaskOfIntReturnType = new MethodWithTaskOfTaskOfIntReturnType(_controller.TaskOfTaskAction);
            var result = await(Task <int>)(await ControllerActionExecutor.ExecuteAsync(
                                               methodWithTaskOfTaskOfIntReturnType.GetMethodInfo(),
                                               _controller,
                                               actionParameters));

            Assert.Equal(inputParam1, result);
        }
예제 #20
0
        public async Task AsyncAction_WithExceptionsAfterAwait()
        {
            int    inputParam1      = 1;
            string inputParam2      = "Second Parameter";
            var    actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskActionThrowAfterAwait);

            await AssertThrowsAsync <ArgumentException>(
                async() =>
                await ControllerActionExecutor.ExecuteAsync(
                    methodWithTaskOfIntReturnType.GetMethodInfo(),
                    _controller,
                    actionParameters),
                "Argument Exception");
        }
예제 #21
0
        public async Task ParametersInRandomOrder()
        {
            int    inputParam1 = 1;
            string inputParam2 = "Second Parameter";

            // Note that the order of parameters is reversed
            var actionParameters = new Dictionary <string, object> {
                { "s", inputParam2 }, { "i", inputParam1 }
            };
            var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskValueTypeAction);

            var result = await ControllerActionExecutor.ExecuteAsync(
                methodWithTaskOfIntReturnType.GetMethodInfo(),
                _controller,
                actionParameters);

            Assert.Equal(inputParam1, result);
        }
예제 #22
0
        private async Task <IViewComponentResult> InvokeAsyncCore(ObjectMethodExecutor executor, ViewComponentContext context)
        {
            var component = _viewComponentFactory.CreateViewComponent(context);

            using (_logger.ViewComponentScope(context))
            {
                var arguments = ControllerActionExecutor.PrepareArguments(context.Arguments, executor);

                _diagnosticSource.BeforeViewComponent(context, component);
                _logger.ViewComponentExecuting(context, arguments);

                var startTimestamp = _logger.IsEnabled(LogLevel.Debug) ? Stopwatch.GetTimestamp() : 0;

                object resultAsObject  = null;
                var    taskGenericType = executor.TaskGenericType;

                if (taskGenericType == typeof(IViewComponentResult))
                {
                    resultAsObject = await(Task <IViewComponentResult>) executor.Execute(component, arguments);
                }
                else if (taskGenericType == typeof(string))
                {
                    resultAsObject = await(Task <string>) executor.Execute(component, arguments);
                }
                else if (taskGenericType == typeof(IHtmlContent))
                {
                    resultAsObject = await(Task <IHtmlContent>) executor.Execute(component, arguments);
                }
                else
                {
                    resultAsObject = await executor.ExecuteAsync(component, arguments);
                }

                var viewComponentResult = CoerceToViewComponentResult(resultAsObject);
                _logger.ViewComponentExecuted(context, startTimestamp, viewComponentResult);
                _diagnosticSource.AfterViewComponent(context, viewComponentResult, component);

                _viewComponentFactory.ReleaseViewComponent(context, component);

                return(viewComponentResult);
            }
        }
예제 #23
0
        public async Task AsyncAction_TaskReturnType()
        {
            // Arrange
            var inputParam1      = 1;
            var inputParam2      = "Second Parameter";
            var actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithTaskReturnType = new MethodWithTaskReturnType(_controller.TaskAction);

            // Act
            var result = await ControllerActionExecutor.ExecuteAsync(
                methodWithTaskReturnType.GetMethodInfo(),
                _controller,
                actionParameters);

            // Assert
            Assert.Same(null, result);
        }
예제 #24
0
        protected override async Task <IActionResult> InvokeActionAsync(ActionExecutingContext actionExecutingContext)
        {
            var controllerActionDescriptor = (ControllerActionDescriptor)actionExecutingContext.ActionDescriptor;

            var actionMethodInfo = controllerActionDescriptor.MethodInfo;

            actionMethodInfo = actionExecutingContext.Controller.GetType()
                               .GetMethod(actionMethodInfo.Name, controllerActionDescriptor.Parameters.Select(x => x.ParameterType).ToArray());

            var actionReturnValue = await ControllerActionExecutor.ExecuteAsync(
                actionMethodInfo,
                ActionContext.Controller,
                actionExecutingContext.ActionArguments);

            var actionResult = CreateActionResult(
                actionMethodInfo.ReturnType,
                actionReturnValue);

            return(actionResult);
        }
예제 #25
0
        private async Task <IViewComponentResult> InvokeAsyncCore(
            MethodInfo method,
            ViewComponentContext context)
        {
            if (method == null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var component = CreateComponent(context);

            var result = await ControllerActionExecutor.ExecuteAsync(method, component, context.Arguments);

            return(CoerceToViewComponentResult(result));
        }
예제 #26
0
        public async Task AsyncAction_WithExceptionsAfterAwait()
        {
            // Arrange
            var inputParam1      = 1;
            var inputParam2      = "Second Parameter";
            var actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var methodWithTaskOfIntReturnType = new MethodWithTaskOfIntReturnType(_controller.TaskActionThrowAfterAwait);
            var expectedException             = "Argument Exception";

            // Act & Assert
            var ex = await Assert.ThrowsAsync <ArgumentException>(
                () => ControllerActionExecutor.ExecuteAsync(
                    methodWithTaskOfIntReturnType.GetMethodInfo(),
                    _controller,
                    actionParameters));

            Assert.Equal(expectedException, ex.Message);
        }
예제 #27
0
        public async Task AsyncAction_WithDynamicReturnTypeThrows()
        {
            int    inputParam1      = 1;
            string inputParam2      = "Second Parameter";
            var    actionParameters = new Dictionary <string, object> {
                { "i", inputParam1 }, { "s", inputParam2 }
            };

            var    dynamicTaskMethod = new ReturnTaskAsDynamicValue(_controller.ReturnTaskAsDynamicValue);
            string expectedException = string.Format(
                CultureInfo.CurrentCulture,
                "The method 'ReturnTaskAsDynamicValue' on type '{0}' returned a Task instance even though it is not an asynchronous method.",
                typeof(TestController));

            await AssertThrowsAsync <InvalidOperationException>(
                async() =>
                await ControllerActionExecutor.ExecuteAsync(
                    dynamicTaskMethod.GetMethodInfo(),
                    _controller,
                    actionParameters),
                expectedException);
        }