public async void SelectAsync_AmbiguousActions_LogIsCorrect()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink, enabled: true);

            var actions = new ActionDescriptor[]
            {
                new ActionDescriptor() { DisplayName = "A1" },
                new ActionDescriptor() { DisplayName = "A2" },
            };
            var selector = CreateSelector(actions, loggerFactory);

            var routeContext = CreateRouteContext("POST");
            var actionNames = string.Join(Environment.NewLine, actions.Select(action => action.DisplayName));
            var expectedMessage = "Request matched multiple actions resulting in " +
                $"ambiguity. Matching actions: {actionNames}";

            // Act
            await Assert.ThrowsAsync<AmbiguousActionException>(async () =>
            {
                await selector.SelectAsync(routeContext);
            });

            // Assert
            Assert.Empty(sink.Scopes);
            Assert.Single(sink.Writes);
            Assert.Equal(expectedMessage, sink.Writes[0].State?.ToString());
        }
Example #2
0
        public virtual object ApplyQueryOptions(object value, HttpRequest request, ActionDescriptor descriptor)
        {
            var elementClrType = TypeHelper.GetImplementedIEnumerableType(value.GetType());

            var model = request.ODataProperties().Model;
            if (model == null)
            {
                throw Error.InvalidOperation(SRResources.QueryGetModelMustNotReturnNull);
            }

            var queryContext = new ODataQueryContext(
                model,
                elementClrType,
                request.ODataProperties().Path);

            var queryOptions = new ODataQueryOptions(queryContext, request);

            var enumerable = value as IEnumerable;
            if (enumerable == null)
            {
                // response is single entity.
                return value;
            }

            // response is a collection.
            var query = (value as IQueryable) ?? enumerable.AsQueryable();
            return queryOptions.ApplyTo(query,
                new ODataQuerySettings
                {
                    HandleNullPropagation = HandleNullPropagationOption.True
                });
        }
        public async void SelectAsync_NoMatchedActions_LogIsCorrect()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink);

            var routeContext = CreateRouteContext("POST");

            var actions = new ActionDescriptor[0];
            var selector = CreateSelector(actions, loggerFactory);

            // Act
            var action = await selector.SelectAsync(routeContext);

            // Assert
            Assert.Equal(1, sink.Scopes.Count);
            var scope = sink.Scopes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, scope.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", scope.Scope);

            Assert.Equal(1, sink.Writes.Count);

            var write = sink.Writes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, write.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", write.Scope);
            var values = Assert.IsType<DefaultActionSelectorSelectAsyncValues>(write.State);
            Assert.Equal("DefaultActionSelector.SelectAsync", values.Name);
            Assert.Empty(values.ActionsMatchingRouteConstraints);
            Assert.Empty(values.ActionsMatchingActionConstraints);
            Assert.Empty(values.FinalMatches);
            Assert.Null(values.SelectedAction);

            // (does not throw)
            Assert.NotEmpty(values.Summary);
        }
        public void OnBeforeAction(ActionDescriptor actionDescriptor, HttpContext httpContext, RouteData routeData)
        {
            string name = this.GetNameFromRouteContext(routeData);
            var telemetry = httpContext.RequestServices.GetService<RequestTelemetry>();

            if (!string.IsNullOrEmpty(name) && telemetry != null && telemetry is RequestTelemetry)
            {
                name = httpContext.Request.Method + " " + name;
                ((RequestTelemetry)telemetry).Name = name;
            }
        }
Example #5
0
        public async void SelectAsync_MatchedActions_LogIsCorrect()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink);

            var matched = new ActionDescriptor()
            {
                MethodConstraints = new List<HttpMethodConstraint>()
                {
                    new HttpMethodConstraint(new string[] { "POST" }),
                },
                Parameters = new List<ParameterDescriptor>(),
            };

            var notMatched = new ActionDescriptor()
            {
                Parameters = new List<ParameterDescriptor>(),
            };

            var actions = new ActionDescriptor[] { matched, notMatched };
            var selector = CreateSelector(actions, loggerFactory);

            var routeContext = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(routeContext);

            // Assert
            Assert.Equal(1, sink.Scopes.Count);
            var scope = sink.Scopes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, scope.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", scope.Scope);

            // There is a record for IsEnabled and one for WriteCore.
            Assert.Equal(2, sink.Writes.Count);

            var enabled = sink.Writes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, enabled.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", enabled.Scope);
            Assert.Null(enabled.State);

            var write = sink.Writes[1];
            Assert.Equal(typeof(DefaultActionSelector).FullName, write.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", write.Scope);
            var values = Assert.IsType<DefaultActionSelectorSelectAsyncValues>(write.State);
            Assert.Equal("DefaultActionSelector.SelectAsync", values.Name);
            Assert.NotEmpty(values.ActionsMatchingRouteConstraints);
            Assert.NotEmpty(values.ActionsMatchingRouteAndMethodConstraints);
            Assert.NotEmpty(values.ActionsMatchingWithConstraints);
            Assert.Equal(matched, values.SelectedAction);
        }
Example #6
0
        public void EmptyResult_ExecuteResult_IsANoOp()
        {
            // Arrange
            var emptyResult = new EmptyResult();

            var httpContext = new Mock<HttpContext>(MockBehavior.Strict);
            var routeData = new RouteData();
            var actionDescriptor = new ActionDescriptor();

            var context = new ActionContext(httpContext.Object, routeData, actionDescriptor);

            // Act & Assert (does not throw)
            emptyResult.ExecuteResult(context);
        }
Example #7
0
        public IActionInvoker GetInvoker(RequestContext requestContext, ActionDescriptor descriptor)
        {
            var controllerActionDescriptor = descriptor as ControllerBasedActionDescriptor;

            if (controllerActionDescriptor != null)
            {
                return new ControllerActionInvoker(
                    requestContext,
                    controllerActionDescriptor,
                    _actionResultFactory,
                    _serviceProvider);
            }

            return null;
        }
        public async void SelectAsync_MatchedActions_LogIsCorrect()
        {
            // Arrange
            var sink = new TestSink();
            var loggerFactory = new TestLoggerFactory(sink);

            var matched = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new HttpMethodConstraint(new string[] { "POST" }),
                },
                Parameters = new List<ParameterDescriptor>(),
            };

            var notMatched = new ActionDescriptor()
            {
                Parameters = new List<ParameterDescriptor>(),
            };

            var actions = new ActionDescriptor[] { matched, notMatched };
            var selector = CreateSelector(actions, loggerFactory);

            var routeContext = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(routeContext);

            // Assert
            Assert.Equal(1, sink.Scopes.Count);
            var scope = sink.Scopes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, scope.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", scope.Scope);

            Assert.Equal(1, sink.Writes.Count);

            var write = sink.Writes[0];
            Assert.Equal(typeof(DefaultActionSelector).FullName, write.LoggerName);
            Assert.Equal("DefaultActionSelector.SelectAsync", write.Scope);
            var values = Assert.IsType<DefaultActionSelectorSelectAsyncValues>(write.State);
            Assert.Equal("DefaultActionSelector.SelectAsync", values.Name);
            Assert.Equal<ActionDescriptor>(actions, values.ActionsMatchingRouteConstraints);
            Assert.Equal<ActionDescriptor>(new[] { matched }, values.ActionsMatchingActionConstraints);
            Assert.Equal(matched, Assert.Single(values.FinalMatches));
            Assert.Equal(matched, values.SelectedAction);
        }
        public void HttpStatusCodeResult_ExecuteResultSetsResponseStatusCode()
        {
            // Arrange
            var result = new HttpStatusCodeResult(StatusCodes.Status404NotFound);

            var httpContext = new DefaultHttpContext();
            var routeData = new RouteData();
            var actionDescriptor = new ActionDescriptor();

            var context = new ActionContext(httpContext, routeData, actionDescriptor);

            // Act
            result.ExecuteResult(context);

            // Assert
            Assert.Equal(StatusCodes.Status404NotFound, httpContext.Response.StatusCode);
        }
        public void Accept_MatchesForMachingRequestContentType(string contentType)
        {
            // Arrange
            var constraint = new ConsumesAttribute("application/json", "text/xml");
            var action = new ActionDescriptor()
            {
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(constraint, FilterScope.Action) }
            };

            var context = new ActionConstraintContext();
            context.Candidates = new List<ActionSelectorCandidate>()
            {
                new ActionSelectorCandidate(action, new [] { constraint }),
            };

            context.CurrentCandidate = context.Candidates[0];
            context.RouteContext = CreateRouteContext(contentType: contentType);

            // Act & Assert
            Assert.True(constraint.Accept(context));
        }
        public async Task SelectAsync_ConstraintsInOrder_MultipleStages()
        {
            // Arrange
            var best = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = true, Order = 0, },
                    new BooleanConstraint() { Pass = true, Order = 1, },
                    new BooleanConstraint() { Pass = true, Order = 2, },
                },
            };

            var worst = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = true, Order = 0, },
                    new BooleanConstraint() { Pass = true, Order = 1, },
                    new BooleanConstraint() { Pass = true, Order = 3, },
                },
            };

            var actions = new ActionDescriptor[] { best, worst };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Same(action, best);
        }
        public async Task SelectAsync_CustomProvider()
        {
            // Arrange
            var actionWithConstraints = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraintMarker() { Pass = true },
                }
            };

            var actionWithoutConstraints = new ActionDescriptor()
            {
                Parameters = new List<ParameterDescriptor>(),
            };

            var actions = new ActionDescriptor[] { actionWithConstraints, actionWithoutConstraints, };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Same(action, actionWithConstraints);
        }
        public async Task SelectAsync_ActionConstraintFactory_ReturnsNull()
        {
            // Arrange
            var nullConstraint = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new ConstraintFactory()
                    {
                    },
                }
            };

            var actions = new ActionDescriptor[] { nullConstraint };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Same(action, nullConstraint);
        }
Example #14
0
 public ActionContext([NotNull] RouteContext routeContext, [NotNull] ActionDescriptor actionDescriptor)
     : this(routeContext.HttpContext, routeContext.RouteData, actionDescriptor)
 {
 }
Example #15
0
        public IActionInvoker CreateInvoker(RequestContext requestContext)
        {
            ActionDescriptor descriptor = _actionDescriptorProvider.CreateDescriptor(requestContext);

            return _actionInvokerProvider.GetInvoker(requestContext, descriptor);
        }
        public void Accept_ForNoRequestType_ReturnsTrueForAllConstraints(string contentType)
        {
            // Arrange
            var constraint1 = new ConsumesAttribute("application/json");
            var actionWithConstraint = new ActionDescriptor()
            {
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) }
            };

            var constraint2 = new ConsumesAttribute("text/xml");
            var actionWithConstraint2 = new ActionDescriptor()
            {
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(constraint2, FilterScope.Action) }
            };

            var actionWithoutConstraint = new ActionDescriptor();

            var context = new ActionConstraintContext();
            context.Candidates = new List<ActionSelectorCandidate>()
            {
                new ActionSelectorCandidate(actionWithConstraint, new [] { constraint1 }),
                new ActionSelectorCandidate(actionWithConstraint2, new [] { constraint2 }),
            };

            context.RouteContext = CreateRouteContext(contentType: contentType);

            // Act & Assert
            context.CurrentCandidate = context.Candidates[0];
            Assert.True(constraint1.Accept(context));
            context.CurrentCandidate = context.Candidates[1];
            Assert.True(constraint2.Accept(context));
        }
        public async Task SelectAsync_Ambiguous()
        {
            // Arrange
            var expectedMessage =
                "Multiple actions matched. " +
                "The following actions matched route data and had all constraints satisfied:" + Environment.NewLine +
                Environment.NewLine +
                "Ambiguous1" + Environment.NewLine +
                "Ambiguous2";

            var actions = new ActionDescriptor[]
            {
                CreateAction(area: null, controller: "Store", action: "Buy"),
                CreateAction(area: null, controller: "Store", action: "Buy"),
                CreateAction(area: null, controller: "Store", action: "Cart"),
            };

            actions[0].DisplayName = "Ambiguous1";
            actions[1].DisplayName = "Ambiguous2";

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("GET");

            context.RouteData.Values.Add("controller", "Store");
            context.RouteData.Values.Add("action", "Buy");

            // Act
            var ex = await Assert.ThrowsAsync<AmbiguousActionException>(async () =>
            {
                await selector.SelectAsync(context);
            });

            // Assert
            Assert.Equal(expectedMessage, ex.Message);
        }
Example #18
0
        private async Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor)
        {
            var services = context.HttpContext.RequestServices;
            Debug.Assert(services != null);

            var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor);

            var contextAccessor = services.GetRequiredService<IScopedInstance<ActionContext>>();
            contextAccessor.Value = actionContext;
            var invokerFactory = services.GetRequiredService<IActionInvokerFactory>();
            var invoker = invokerFactory.CreateInvoker(actionContext);
            if (invoker == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(
                        actionDescriptor.DisplayName));
            }

            await invoker.InvokeAsync();
        }
Example #19
0
 private bool MatchDynamicConstraints(ActionDescriptor descriptor, RouteContext context)
 {
     return descriptor.DynamicConstraints == null ||
             descriptor.DynamicConstraints.All(c => c.Accept(context));
 }
Example #20
0
        private async Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor)
        {
            var services = context.HttpContext.RequestServices;
            Debug.Assert(services != null);

            var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor);

            var optionsAccessor = services.GetRequiredService<IOptions<MvcOptions>>();
            actionContext.ModelState.MaxAllowedErrors = optionsAccessor.Options.MaxModelValidationErrors;

            var contextAccessor = services.GetRequiredService<IScopedInstance<ActionContext>>();
            contextAccessor.Value = actionContext;
            var invokerFactory = services.GetRequiredService<IActionInvokerFactory>();
            var invoker = invokerFactory.CreateInvoker(actionContext);
            if (invoker == null)
            {
                LogActionSelection(actionSelected: true, actionInvoked: false, handled: context.IsHandled);

                throw new InvalidOperationException(
                    Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(
                        actionDescriptor.DisplayName));
            }

            await invoker.InvokeAsync();
        }
        public void OnResourceExecuting_ForAContentTypeMatch_IsNoOp(string contentType)
        {
            // Arrange
            var httpContext = new DefaultHttpContext();
            httpContext.Request.ContentType = contentType;
            var consumesFilter = new ConsumesAttribute("application/json", "application/xml");
            var actionWithConstraint = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>() { consumesFilter },
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(consumesFilter, FilterScope.Action) }
            };
            var actionContext = new ActionContext(httpContext, new RouteData(), actionWithConstraint);
            var resourceExecutingContext = new ResourceExecutingContext(actionContext, new[] { consumesFilter });

            // Act
            consumesFilter.OnResourceExecuting(resourceExecutingContext);

            // Assert
            Assert.Null(resourceExecutingContext.Result);
        }
        public async Task SelectAsync_Fallback_ToActionWithoutConstraints()
        {
            // Arrange
            var nomatch1 = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = true, Order = 0, },
                    new BooleanConstraint() { Pass = true, Order = 1, },
                    new BooleanConstraint() { Pass = false, Order = 2, },
                },
            };

            var nomatch2 = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = true, Order = 0, },
                    new BooleanConstraint() { Pass = true, Order = 1, },
                    new BooleanConstraint() { Pass = false, Order = 3, },
                },
            };

            var best = new ActionDescriptor();

            var actions = new ActionDescriptor[] { best, nomatch1, nomatch2 };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Same(action, best);
        }
Example #23
0
        private async Task InvokeActionAsync(RouteContext context, ActionDescriptor actionDescriptor)
        {
            var actionContext = new ActionContext(context.HttpContext, context.RouteData, actionDescriptor);
            _actionContextAccessor.ActionContext = actionContext;
            
            var invoker = _actionInvokerFactory.CreateInvoker(actionContext);
            if (invoker == null)
            {
                throw new InvalidOperationException(
                    Resources.FormatActionInvokerFactory_CouldNotCreateInvoker(
                        actionDescriptor.DisplayName));
            }

            await invoker.InvokeAsync();
        }
        public async Task SelectAsync_WithCatchAll_NoMatch()
        {
            // Arrange
            var actions = new ActionDescriptor[]
            {
                CreateAction(area: null, controller: "Store", action: "Buy"),
                CreateAction(area: null, controller: "Store", action: "Buy"),
                CreateAction(area: null, controller: "Store", action: "Buy"),
            };

            actions[0].RouteConstraints.Add(new RouteDataActionConstraint("country", "CA"));
            actions[1].RouteConstraints.Add(new RouteDataActionConstraint("country", "US"));
            actions[2].RouteConstraints.Add(RouteDataActionConstraint.CreateCatchAll("country"));

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("GET");

            context.RouteData.Values.Add("controller", "Store");
            context.RouteData.Values.Add("action", "Buy");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Null(action);
        }
Example #25
0
        private static ActionDescriptor CreateAction(string area, string controller, string action)
        {
            var actionDescriptor = new ActionDescriptor()
            {
                Name = string.Format("Area: {0}, Controller: {1}, Action: {2}", area, controller, action),
                RouteConstraints = new List<RouteDataActionConstraint>(),
            };

            actionDescriptor.RouteConstraints.Add(
                area == null ?
                new RouteDataActionConstraint("area", RouteKeyHandling.DenyKey) :
                new RouteDataActionConstraint("area", area));

            actionDescriptor.RouteConstraints.Add(
                controller == null ?
                new RouteDataActionConstraint("controller", RouteKeyHandling.DenyKey) :
                new RouteDataActionConstraint("controller", controller));

            actionDescriptor.RouteConstraints.Add(
                action == null ?
                new RouteDataActionConstraint("action", RouteKeyHandling.DenyKey) :
                new RouteDataActionConstraint("action", action));

            return actionDescriptor;
        }
 /// <summary>
 /// Sets the value of an property in the <see cref="ActionDescriptor.Properties"/> collection using
 /// the provided value of <typeparamref name="T"/> as the key.
 /// </summary>
 /// <typeparam name="T">The type of the property.</typeparam>
 /// <param name="actionDescriptor">The action descriptor.</param>
 /// <param name="value">The value of the property.</param>
 public static void SetProperty <T>([NotNull] this ActionDescriptor actionDescriptor, [NotNull] T value)
 {
     actionDescriptor.Properties[typeof(T)] = value;
 }
        public void Accept_UnrecognizedMediaType_SelectsTheCandidateWithoutConstraintIfPresent(string contentType)
        {
            // Arrange
            var actionWithoutConstraint = new ActionDescriptor();
            var constraint1 = new ConsumesAttribute("application/json");
            var actionWithConstraint = new ActionDescriptor()
            {
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(constraint1, FilterScope.Action) }
            };

            var constraint2 = new ConsumesAttribute("text/xml");
            var actionWithConstraint2 = new ActionDescriptor()
            {
                FilterDescriptors =
                    new List<FilterDescriptor>() { new FilterDescriptor(constraint2, FilterScope.Action) }
            };

            var context = new ActionConstraintContext();
            context.Candidates = new List<ActionSelectorCandidate>()
            {
                new ActionSelectorCandidate(actionWithConstraint, new [] { constraint1 }),
                new ActionSelectorCandidate(actionWithConstraint2, new [] { constraint2 }),
                new ActionSelectorCandidate(actionWithoutConstraint, new List<IActionConstraint>()),
            };

            context.RouteContext = CreateRouteContext(contentType: contentType);

            // Act & Assert
            context.CurrentCandidate = context.Candidates[0];
            Assert.False(constraint1.Accept(context));

            context.CurrentCandidate = context.Candidates[1];
            Assert.False(constraint2.Accept(context));
        }
Example #28
0
        public async Task SelectAsync_PrefersActionWithConstraints()
        {
            // Arrange
            var actionWithConstraints = new ActionDescriptor()
            {
                MethodConstraints = new List<HttpMethodConstraint>()
                {
                    new HttpMethodConstraint(new string[] { "POST" }),
                },
                Parameters = new List<ParameterDescriptor>(),
            };

            var actionWithoutConstraints = new ActionDescriptor()
            {
                Parameters = new List<ParameterDescriptor>(),
            };

            var actions = new ActionDescriptor[] { actionWithConstraints, actionWithoutConstraints };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Same(action, actionWithConstraints);
        }
 /// <summary>
 /// Determines whether the action selection is valid for the specified route context.
 /// </summary>
 /// <param name="routeContext">The route context.</param>
 /// <param name="action">Information about the action.</param>
 /// <returns>
 /// <see langword="true"/> if the action  selection is valid for the specified context;
 /// otherwise, <see langword="false"/>.
 /// </returns>
 public abstract bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action);
 /// <summary>
 /// Determines whether the action selection is valid for the specified route context.
 /// </summary>
 /// <param name="routeContext">The route context.</param>
 /// <param name="action">Information about the action.</param>
 /// <returns>
 /// <see langword="true"/> if the action  selection is valid for the specified context;
 /// otherwise, <see langword="false"/>.
 /// </returns>
 public abstract bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action);
        public async Task SelectAsync_ConstraintsRejectAll_DifferentStages()
        {
            // Arrange
            var action1 = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = false, Order = 0 },
                    new BooleanConstraint() { Pass = true, Order = 1 },
                },
            };

            var action2 = new ActionDescriptor()
            {
                ActionConstraints = new List<IActionConstraintMetadata>()
                {
                    new BooleanConstraint() { Pass = true, Order = 0 },
                    new BooleanConstraint() { Pass = false, Order = 1 },
                },
            };

            var actions = new ActionDescriptor[] { action1, action2 };

            var selector = CreateSelector(actions);
            var context = CreateRouteContext("POST");

            // Act
            var action = await selector.SelectAsync(context);

            // Assert
            Assert.Null(action);
        }
        private RouteContext CreateRouteContext(
            ActionDescriptor actionDescriptor = null,
            IActionSelector actionSelector = null,
            IActionInvokerFactory invokerFactory = null,
            ILoggerFactory loggerFactory = null,
            IOptions<MvcOptions> optionsAccessor = null,
            object notificationListener = null)
        {
            var mockContextAccessor = new Mock<IScopedInstance<ActionContext>>();

            if (actionDescriptor == null)
            {
                var mockAction = new Mock<ActionDescriptor>();
                actionDescriptor = mockAction.Object;
            }

            if (actionSelector == null)
            {
                var mockActionSelector = new Mock<IActionSelector>();
                mockActionSelector.Setup(a => a.SelectAsync(It.IsAny<RouteContext>()))
                    .Returns(Task.FromResult(actionDescriptor));

                actionSelector = mockActionSelector.Object;
            }

            if (invokerFactory == null)
            {
                var mockInvoker = new Mock<IActionInvoker>();
                mockInvoker.Setup(i => i.InvokeAsync())
                    .Returns(Task.FromResult(true));

                var mockInvokerFactory = new Mock<IActionInvokerFactory>();
                mockInvokerFactory.Setup(f => f.CreateInvoker(It.IsAny<ActionContext>()))
                    .Returns(mockInvoker.Object);

                invokerFactory = mockInvokerFactory.Object;
            }

            if (loggerFactory == null)
            {
                loggerFactory = NullLoggerFactory.Instance;
            }

            if (optionsAccessor == null)
            {
                optionsAccessor = new MockMvcOptionsAccessor();
            }

            var notifier = new Notifier(new NotifierMethodAdapter());
            if (notificationListener != null)
            {
                notifier.EnlistTarget(notificationListener);
            }

            var httpContext = new Mock<HttpContext>();
            httpContext.Setup(h => h.RequestServices.GetService(typeof(IScopedInstance<ActionContext>)))
                .Returns(mockContextAccessor.Object);
            httpContext.Setup(h => h.RequestServices.GetService(typeof(IActionSelector)))
                .Returns(actionSelector);
            httpContext.Setup(h => h.RequestServices.GetService(typeof(IActionInvokerFactory)))
                .Returns(invokerFactory);
            httpContext.Setup(h => h.RequestServices.GetService(typeof(ILoggerFactory)))
                .Returns(loggerFactory);
            httpContext.Setup(h => h.RequestServices.GetService(typeof(MvcMarkerService)))
                 .Returns(new MvcMarkerService());
            httpContext.Setup(h => h.RequestServices.GetService(typeof(IOptions<MvcOptions>)))
                 .Returns(optionsAccessor);
            httpContext.Setup(h => h.RequestServices.GetService(typeof(INotifier)))
                .Returns(notifier);

            return new RouteContext(httpContext.Object);
        }
        private static HttpContext GetHttpContext(ActionDescriptor actionDescriptor)
        {
            var actionProvider = new Mock<IActionDescriptorProvider>(MockBehavior.Strict);

            actionProvider
                .SetupGet(p => p.Order)
                .Returns(DefaultOrder.DefaultFrameworkSortOrder);

            actionProvider
                .Setup(p => p.OnProvidersExecuting(It.IsAny<ActionDescriptorProviderContext>()))
                .Callback<ActionDescriptorProviderContext>(c => c.Results.Add(actionDescriptor));

            actionProvider
                .Setup(p => p.OnProvidersExecuted(It.IsAny<ActionDescriptorProviderContext>()))
                .Verifiable();

            var context = new Mock<HttpContext>();
            context.Setup(o => o.RequestServices
                                .GetService(typeof(IEnumerable<IActionDescriptorProvider>)))
                   .Returns(new[] { actionProvider.Object });

            context.Setup(o => o.RequestServices
                               .GetService(typeof(IActionDescriptorsCollectionProvider)))
                   .Returns(new DefaultActionDescriptorsCollectionProvider(context.Object.RequestServices));
            return context.Object;
        }
Example #34
0
        private bool IsApplicable(ActionDescriptor actionDescriptor)
        {
            // If there are multiple IConsumeActionConstraints which are defined at the class and
            // at the action level, the one closest to the action overrides the others. To ensure this
            // we take advantage of the fact that ConsumesAttribute is both an IActionFilter and an
            // IConsumeActionConstraint. Since filterdescriptor collection is ordered (the last filter is the one
            // closest to the action), we apply this constraint only if there is no IConsumeActionConstraint after this.
            return actionDescriptor.FilterDescriptors.Last(
                filter => filter.Filter is IConsumesActionConstraint).Filter == this;

        }
Example #35
0
 private bool MatchDynamicConstraints(ActionDescriptor descriptor, RouteContext context)
 {
     return(descriptor.DynamicConstraints == null ||
            descriptor.DynamicConstraints.All(c => c.Accept(context)));
 }