private ControllerActionDescriptor CreateActionDescriptor(
            string httpMethod, string routeTemplate, string actionFixtureName)
        {
            var descriptor = new ControllerActionDescriptor();
            descriptor.SetProperty(new ApiDescriptionActionData());
            descriptor.DisplayName = actionFixtureName;

            descriptor.ActionConstraints = new List<IActionConstraintMetadata>
            {
                new HttpMethodConstraint(new[] { httpMethod })
            };
            descriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate };

            descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName);
            if (descriptor.MethodInfo == null)
                throw new InvalidOperationException(
                    string.Format("{0} is not declared in ActionFixtures", actionFixtureName));

            descriptor.Parameters = descriptor.MethodInfo.GetParameters()
                .Select(paramInfo => new ParameterDescriptor
                    {
                        Name = paramInfo.Name,
                        ParameterType = paramInfo.ParameterType,
                        BindingInfo = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false))
                    })
                .ToList();

            // Set some additional properties - typically done via IApplicationModelConvention
            var attributes = descriptor.MethodInfo.GetCustomAttributes(true);
            descriptor.Properties.Add("ActionAttributes", attributes);
            descriptor.Properties.Add("IsObsolete", attributes.OfType<ObsoleteAttribute>().Any());

            return descriptor;
        }
        public ControllerActionInvoker(
            [NotNull] ActionContext actionContext,
            [NotNull] IReadOnlyList<IFilterProvider> filterProviders,
            [NotNull] IControllerFactory controllerFactory,
            [NotNull] ControllerActionDescriptor descriptor,
            [NotNull] IInputFormattersProvider inputFormatterProvider,
            [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder,
            [NotNull] IModelBinderProvider modelBinderProvider,
            [NotNull] IModelValidatorProviderProvider modelValidatorProviderProvider,
            [NotNull] IValueProviderFactoryProvider valueProviderFactoryProvider,
            [NotNull] IScopedInstance<ActionBindingContext> actionBindingContextAccessor,
            [NotNull] ITempDataDictionary tempData)
            : base(
                  actionContext, 
                  filterProviders,
                  inputFormatterProvider, 
                  modelBinderProvider, 
                  modelValidatorProviderProvider, 
                  valueProviderFactoryProvider,
                  actionBindingContextAccessor)
        {
            _descriptor = descriptor;
            _controllerFactory = controllerFactory;
            _argumentBinder = controllerActionArgumentBinder;
            _tempData = tempData;

            if (descriptor.MethodInfo == null)
            {
                throw new ArgumentException(
                    Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo",
                                                               typeof(ControllerActionDescriptor)),
                    "descriptor");
            }
        }
        public void CreateController_UsesControllerActivatorToInstantiateController()
        {
            // Arrange
            var expected = new MyController();
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(MyController).GetTypeInfo()
            };
            var httpContext = new DefaultHttpContext();
            httpContext.RequestServices = GetServices();
            var actionContext = new ActionContext(httpContext,
                                                  new RouteData(),
                                                  actionDescriptor);
            var activator = new Mock<IControllerActivator>();
            activator.Setup(a => a.Create(actionContext, typeof(MyController)))
                     .Returns(expected)
                     .Verifiable();

            var controllerFactory = new DefaultControllerFactory(activator.Object);

            // Act
            var result = controllerFactory.CreateController(actionContext);

            // Assert
            var controller = Assert.IsType<MyController>(result);
            Assert.Same(expected, controller);
            activator.Verify();
        }
		public void VisiblityCanBeChangedViaAttribute(Type controllerType, bool exposeAllRoutes, bool expected)
		{
			var controllerName = controllerType.Name.Replace("Controller", string.Empty);
			var config = new RouteJsConfiguration { ExposeAllRoutes = exposeAllRoutes };

			var descriptor = new ControllerActionDescriptor
			{
				ControllerName = controllerName,
				ControllerTypeInfo = controllerType.GetTypeInfo(),
			};

			var descriptorProvider = new Mock<IActionDescriptorsCollectionProvider>();
			descriptorProvider.Setup(x => x.ActionDescriptors).Returns(new ActionDescriptorsCollection(
				new List<ActionDescriptor> { descriptor },
				version: 1
			));

			var filter = new DefaultRouteFilter(config, descriptorProvider.Object);
			var result = filter.AllowRoute(new RouteInfo
			{
				Defaults = new Dictionary<string, object>
				{
					{"controller", controllerName},
				},
			});
			Assert.Equal(expected, result);
	    }
        public void GetApiDescription_IgnoresActionWithoutApiExplorerData()
        {
            // Arrange
            var action = new ControllerActionDescriptor();

            // Act
            var descriptions = GetApiDescriptions(action);

            // Assert
            Assert.Empty(descriptions);
        }
示例#6
0
        /// <summary>
        /// Get the name of exception policy to handle the exception.
        /// </summary>
        /// <param name="context">The current <see cref="ExceptionContext"/>.</param>
        /// <returns>The name of exception policy to handle the exception.</returns>
        protected virtual string GetExceptionPolicy(Filters.ExceptionContext context)
        {
            Guard.ArgumentNotNull(context, nameof(context));
            if (!string.IsNullOrEmpty(this.ExceptionPolicy))
            {
                return(this.ExceptionPolicy);
            }

            ControllerActionDescriptor actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;

            if (null != actionDescriptor)
            {
                var attribute = actionDescriptor.MethodInfo.GetCustomAttribute <ExceptionPolicyAttribute>()
                                ?? actionDescriptor.ControllerTypeInfo.GetCustomAttribute <ExceptionPolicyAttribute>();
                if (null != attribute)
                {
                    return(attribute.PolicyName);
                }
            }
            return(_options.ExceptionPolicy);
        }
示例#7
0
        public void Authen_Withusermodifyprivilege_Test()
        {
            ControllerActionDescriptor controllerActionDescriptor = new ControllerActionDescriptor();

            controllerActionDescriptor.MethodInfo = this.GetType().GetMethod(nameof(ModifyUser), BindingFlags.Public | BindingFlags.Instance);

            var actionContext = new ActionContext();

            actionContext.ActionDescriptor = controllerActionDescriptor;
            actionContext.HttpContext      = new Mock <HttpContext>().Object;
            actionContext.RouteData        = new RouteData();
            var filterContext = new ExceptionContext(actionContext, new List <IFilterMetadata>());

            var authenQuery = new ExecuteContextAuthen(filterContext, new UserWithUserQueryPrivilege());

            Assert.IsTrue(authenQuery.Authen(new DefaultParceAuthenTypeAccordParameterName()) == EnumAuthenResult.NotAuthened, "有用户查询权限的人访问 ModifyUser 时不允许访问");

            var authenModify = new ExecuteContextAuthen(filterContext, new UserWithUserModifyPrivilege());

            Assert.IsTrue(authenModify.Authen(new DefaultParceAuthenTypeAccordParameterName()) == EnumAuthenResult.Authened, "有用户查询权限的人访问 ModifyUser 时不允许访问");
        }
示例#8
0
        public void FindsActionWithExactContentRouteType()
        {
            var actionA = new ControllerActionDescriptor {
                ControllerName = "lorem", MethodInfo = typeof(MyController).GetMethod(nameof(MyController.ActionWithTypeAParameter))
            };
            var actionB = new ControllerActionDescriptor {
                ControllerName = "lorem", MethodInfo = typeof(MyController).GetMethod(nameof(MyController.ActionWithTypeBParameter))
            };

            var serviceProvider = Mock.Of <IServiceProvider>();
            var actions         = Mock.Of <IActionDescriptorCollectionProvider>();

            Mock.Get(serviceProvider).Setup(s => s.GetService(typeof(IActionDescriptorCollectionProvider))).Returns(actions);
            Mock.Get(actions).SetupGet(a => a.ActionDescriptors).Returns(new ActionDescriptorCollection(new List <ActionDescriptor> {
                actionA, actionB
            }.AsReadOnly(), 0));

            var result = new ContentRouteActionFinder(serviceProvider).Find("lorem", new MyContentA());

            Assert.Same(actionA, result);
        }
示例#9
0
        /// <summary>
        /// Infers the name of the page number parameter.
        /// </summary>
        /// <param name="cad">The <see cref="ControllerActionDescriptor"/> which contains the controller action definition information.</param>
        /// <returns>The name of the page number parameter, or null, if the name cannot be inferred.</returns>
        private static string InferPageNumberParameterName(ControllerActionDescriptor cad)
        {
            if (cad.Parameters.Any(p => p.ParameterType == typeof(int) && p.Name.Equals("page", StringComparison.OrdinalIgnoreCase)))
            {
                return("page");
            }

            if (cad.Parameters.Any(p => p.ParameterType == typeof(int) && p.Name.Equals("pageNumber", StringComparison.OrdinalIgnoreCase)))
            {
                return("pageNumber");
            }

            var pageNumberParameter = cad.MethodInfo.GetParameters().FirstOrDefault(x => x.IsDefined(typeof(PageNumberAttribute)));

            if (pageNumberParameter != null)
            {
                return(pageNumberParameter.Name);
            }

            return(null);
        }
        private static string GetActionDesciption(ControllerActionDescriptor actionDescriptor)
        {
            // controller and action details
            StringBuilder action = new StringBuilder();

            if (actionDescriptor.MethodInfo.ReturnType != null)
            {
                action.Append(actionDescriptor.MethodInfo.ReturnType.Name + " ");
            }
            else
            {
                action.Append("void ");
            }

            action.Append(actionDescriptor.ControllerTypeInfo.FullName);
            action.Append(".");
            action.Append(actionDescriptor.MethodInfo.Name + "(");
            action.Append(string.Join(",", actionDescriptor.MethodInfo.GetParameters().Select(p => p.ParameterType.Name)));
            action.Append(")");
            return(action.ToString());
        }
        /// <summary>判断控制器是否归属于魔方管辖</summary>
        /// <param name="controllerActionDescriptor"></param>
        /// <returns></returns>
        public static Boolean Contains(ControllerActionDescriptor controllerActionDescriptor)
        {
            // 判断控制器是否在管辖范围之内,不拦截其它控制器的异常信息
            var controller = controllerActionDescriptor.ControllerTypeInfo;
            var ns         = controller.Namespace;

            if (!ns.EndsWith(".Controllers"))
            {
                return(false);
            }

            if (_areas == null)
            {
                _areas = new HashSet <String>(Areas.Select(e => e.Namespace));
            }

            // 该控制器父级命名空间必须有对应的区域注册类,才会拦截其异常
            ns = ns.TrimEnd(".Controllers");
            //return Areas.Any(e => e.Namespace == ns);
            return(_areas.Contains(ns));
        }
示例#12
0
        private static ClientIdGetter GetSingleClientIdGetter(ControllerActionDescriptor controllerActionDescriptor)
        {
            if (controllerActionDescriptor.MethodInfo.GetCustomAttribute <SkipMarginTradingEnabledCheckAttribute>() != null)
            {
                return(null);
            }

            var clientIdGetters = GetClientIdGetters(controllerActionDescriptor.Parameters).ToList();

            switch (clientIdGetters.Count)
            {
            case 0:
                return(null);

            case 1:
                return(clientIdGetters[0]);

            default:
                throw new InvalidOperationException("A controller action cannot have more then one ClientId in its parameters");
            }
        }
示例#13
0
        static ControllerActionDescriptor Clone(ControllerActionDescriptor action, AttributeRouteInfo attributeRouteInfo)
        {
            var clone = new ControllerActionDescriptor()
            {
                ActionConstraints  = action.ActionConstraints,
                ActionName         = action.ActionName,
                AttributeRouteInfo = attributeRouteInfo,
                BoundProperties    = action.BoundProperties,
                ControllerName     = action.ControllerName,
                ControllerTypeInfo = action.ControllerTypeInfo,
                DisplayName        = action.DisplayName,
                EndpointMetadata   = action.EndpointMetadata,
                FilterDescriptors  = action.FilterDescriptors,
                MethodInfo         = action.MethodInfo,
                Parameters         = action.Parameters,
                Properties         = action.Properties,
                RouteValues        = action.RouteValues,
            };

            return(clone);
        }
        public void BodyContentScraper_should_ignore_params_if_they_are_included_as_routing_constraints()
        {
            // arrange
            var routeInformation = new RouteInformation
            {
                RouteTemplate = "/api/{foo}/test",
                HttpMethod    = "POST"
            };

            // this will not run in asp.net core but just to be sure the package support 1 body param
            var description = new ControllerActionDescriptor
            {
                MethodInfo = typeof(FakeController).GetMethod("PostWithDuplicatedRouteAndBodyParam")
            };

            // act
            BodyContentScraper.CompleteBodyRequiredContent(routeInformation, description);

            // assert
            Assert.Empty(routeInformation.BodyParams);
        }
示例#15
0
        private static void AddProperties(
            ControllerActionDescriptor actionDescriptor,
            ActionModel action,
            ControllerModel controller,
            ApplicationModel application)
        {
            foreach (var item in application.Properties)
            {
                actionDescriptor.Properties[item.Key] = item.Value;
            }

            foreach (var item in controller.Properties)
            {
                actionDescriptor.Properties[item.Key] = item.Value;
            }

            foreach (var item in action.Properties)
            {
                actionDescriptor.Properties[item.Key] = item.Value;
            }
        }
示例#16
0
        public override void OnActionExecuting(ActionExecutingContext actionContext)
        {
            string operationId = Convert.ToString(actionContext.RouteData.Values["action"]);

            if (!string.IsNullOrEmpty(operationId))
            {
                actionContext.HttpContext.Response.Headers.Add("X-Operation-Id", operationId);
            }

            //// Add debug logs for each action call start
            ControllerActionDescriptor controllerActionDescriptor = actionContext.ActionDescriptor as ControllerActionDescriptor;

            actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ActionRquestData", actionContext.ActionArguments));
            actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ControllerName", controllerActionDescriptor.ControllerName));
            actionContext.HttpContext.Items.Add(new KeyValuePair <object, object>("ActionName", controllerActionDescriptor.ActionName));
            if (!actionContext.ModelState.IsValid)
            {
                actionContext.Result = new ValidationFailedResult(actionContext.ModelState);
            }
            base.OnActionExecuting(actionContext);
        }
示例#17
0
        public void CreateController_ThrowsIfPropertyCannotBeActivated()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerThatCannotBeActivated).GetTypeInfo()
            };
            var services    = GetServices();
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act and Assert
            var exception = Assert.Throws <InvalidOperationException>(() => factory.CreateController(context));

            Assert.Equal("The property 'Service' on controller '" + typeof(ControllerThatCannotBeActivated) +
                         "' cannot be activated.", exception.Message);
        }
示例#18
0
        /// <summary>
        /// 获取ActionModel
        /// </summary>
        /// <param name="actionDescriptor"></param>
        private static ActionModel GetActionModel(ControllerActionDescriptor actionDescriptor)
        {
            ActionModel action = new ActionModel()
            {
                Id       = TypeHelper.GetMethodModuleMark(actionDescriptor.MethodInfo),
                AreaName = actionDescriptor.RouteValues.Keys.Contains("area") ?
                           actionDescriptor.RouteValues["area"] : null,
                ControllerName = actionDescriptor.ControllerName,
                ActionName     = actionDescriptor.ActionName,
                ActionFullName = actionDescriptor.DisplayName,
                RouteTemplate  = actionDescriptor.AttributeRouteInfo?.Template,

                CustomAttrList = actionDescriptor.MethodInfo.CustomAttributes.Select((a, index) =>
                                                                                     GetCustomAttribute(a, index)).ToList(),
                InputParameters = actionDescriptor.Parameters.Select((a, index) =>
                                                                     GetParam(((ControllerParameterDescriptor)a).ParameterInfo)).ToList(),
                ReturnParameter = GetParam(actionDescriptor.MethodInfo.ReturnParameter)
            };

            return(action);
        }
        /// <summary>
        /// Provides filters to apply to the specified action.
        /// </summary>
        /// <param name="context">The filter context.</param>
        public void OnProvidersExecuting(FilterProviderContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            // Actions with a bound parameter of type ODataQueryOptions do not support the query filter
            // The assumption is that the action will handle the querying within the action implementation
            ControllerActionDescriptor controllerActionDescriptor = context.ActionContext.ActionDescriptor as ControllerActionDescriptor;

            if (controllerActionDescriptor != null)
            {
                Type returnType = controllerActionDescriptor.MethodInfo.ReturnType;
                if (ShouldAddFilter(context, returnType, controllerActionDescriptor))
                {
                    var filterDesc = new FilterDescriptor(QueryFilter, FilterScope.Global);
                    context.Results.Add(new FilterItem(filterDesc, QueryFilter));
                }
            }
        }
示例#20
0
        public void GetControllerActionMethodExecutor_CachesExecutor()
        {
            // Arrange
            var services = CreateServices();
            var cache    = CreateCache(new DefaultFilterProvider());

            var action = new ControllerActionDescriptor()
            {
                FilterDescriptors = new[]
                {
                    new FilterDescriptor(new TestFilterFactory()
                    {
                        IsReusable = false
                    }, FilterScope.Action),
                    new FilterDescriptor(new TestFilter(), FilterScope.Action),
                },
                MethodInfo = typeof(ControllerActionInvokerCache).GetMethod(
                    nameof(ControllerActionInvokerCache.GetControllerActionMethodExecutor)),
                ControllerTypeInfo = typeof(ControllerActionInvokerCache).GetTypeInfo()
            };

            var context = new ControllerContext(
                new ActionContext(new DefaultHttpContext(),
                                  new RouteData(),
                                  action));

            // Act - 1
            var executor1 = cache.GetControllerActionMethodExecutor(context);

            Assert.NotNull(executor1);

            var filters1 = cache.GetFilters(context);

            Assert.NotNull(filters1);

            // Act - 2
            var executor2 = cache.GetControllerActionMethodExecutor(context);

            Assert.Same(executor1, executor2);
        }
    public Func <ControllerContext, object> CreateControllerFactory(ControllerActionDescriptor descriptor)
    {
        if (descriptor == null)
        {
            throw new ArgumentNullException(nameof(descriptor));
        }

        var controllerType = descriptor.ControllerTypeInfo?.AsType();

        if (controllerType == null)
        {
            throw new ArgumentException(Resources.FormatPropertyOfTypeCannotBeNull(
                                            nameof(descriptor.ControllerTypeInfo),
                                            nameof(descriptor)),
                                        nameof(descriptor));
        }

        if (_factoryCreateController != null)
        {
            return(_factoryCreateController);
        }

        var controllerActivator = _activatorProvider.CreateActivator(descriptor);
        var propertyActivators  = GetPropertiesToActivate(descriptor);

        object CreateController(ControllerContext controllerContext)
        {
            var controller = controllerActivator(controllerContext);

            for (var i = 0; i < propertyActivators.Length; i++)
            {
                var propertyActivator = propertyActivators[i];
                propertyActivator(controllerContext, controller);
            }

            return(controller);
        }

        return(CreateController);
    }
示例#22
0
        public async Task GetReturnsPublicCategoriesWhenUserNotAdministratorTest()
        {
            var claims = new List <Claim>
            {
                new Claim("sub", Guid.NewGuid().ToString())
            };
            var identity   = new ClaimsIdentity(claims, "testing", "sub", "role");
            var principal  = new ClaimsPrincipal(identity);
            var categories = Model.Create <List <Category> >();

            var query       = Substitute.For <ICategoryQuery>();
            var command     = Substitute.For <ICategoryCommand>();
            var httpContext = Substitute.For <HttpContext>();

            var routerData        = new RouteData();
            var actionDescriptor  = new ControllerActionDescriptor();
            var actionContext     = new ActionContext(httpContext, routerData, actionDescriptor);
            var controllerContext = new ControllerContext(actionContext);

            httpContext.User = principal;

            using (var tokenSource = new CancellationTokenSource())
            {
                query.GetCategories(ReadType.VisibleOnly, tokenSource.Token).Returns(categories);

                using (var target = new CategoriesController(query, command))
                {
                    target.ControllerContext = controllerContext;

                    var actual = await target.Get(tokenSource.Token).ConfigureAwait(false);

                    actual.Should().BeOfType <OkObjectResult>();

                    var result       = actual.As <OkObjectResult>();
                    var resultValues = result.Value as IEnumerable <PublicCategory>;

                    resultValues.Should().BeEquivalentTo(categories, opt => opt.ExcludingMissingMembers());
                }
            }
        }
示例#23
0
        private static bool IsActionAllowAnonymous(ControllerActionDescriptor controllerActionDescriptor)
        {
            // If action have any AllowAnonymousAttribute => Allow Anonymous
            bool isActionAllowAnonymous =
                controllerActionDescriptor.MethodInfo.GetCustomAttributes <AllowAnonymousAttribute>(true).Any();

            if (isActionAllowAnonymous)
            {
                return(true);
            }

            var isActionHaveAnyPermission =
                controllerActionDescriptor.MethodInfo.GetCustomAttributes <AuthAttribute>(true).Any();

            bool isCombineAuthorize =
                controllerActionDescriptor.MethodInfo.GetCustomAttributes <CombineAuthAttribute>(true).Any();

            if (!isCombineAuthorize && isActionHaveAnyPermission)
            {
                return(false);
            }

            bool isControllerAllowAnonymous =
                controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes <AllowAnonymousAttribute>(true).Any();

            if (isControllerAllowAnonymous)
            {
                return(true);
            }

            if (!isActionHaveAnyPermission)
            {
                var isControllerHaveAnyRole =
                    controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes <AuthAttribute>(true).Any();

                return(!isControllerHaveAnyRole);
            }

            return(false);
        }
示例#24
0
        protected internal IRouteDetails GetRouteDetails(ApiDescription desc)
        {
            var routeDetails = new AspNetCoreRouteDetails
            {
                HttpMethods = GetHttpMethods(desc)
            };

            if (desc.ActionDescriptor.AttributeRouteInfo?.Template != null)
            {
                routeDetails.RouteTemplate = desc.ActionDescriptor.AttributeRouteInfo.Template;
            }
            else
            {
                ControllerActionDescriptor cdesc = desc.ActionDescriptor as ControllerActionDescriptor;
                routeDetails.RouteTemplate = $"/{cdesc.ControllerName}/{cdesc.ActionName}";
            }

            List <string> produces = new List <string>();

            foreach (var respTypes in desc.SupportedResponseTypes)
            {
                foreach (var format in respTypes.ApiResponseFormats)
                {
                    produces.Add(format.MediaType);
                }
            }

            routeDetails.Produces = produces;

            List <string> consumes = new List <string>();

            foreach (var reqTypes in desc.SupportedRequestFormats)
            {
                consumes.Add(reqTypes.MediaType);
            }

            routeDetails.Consumes = consumes;

            return(routeDetails);
        }
示例#25
0
        public async Task AttributeRouting_WithControllerActionDescriptor()
        {
            // Arrange
            var controllerType = typeof(HomeController);
            var actionMethod   = controllerType.GetMethod("Index");

            var action = new ControllerActionDescriptor();

            action.DisplayName      = "Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index";
            action.MethodInfo       = actionMethod;
            action.RouteConstraints = new List <RouteDataActionConstraint>()
            {
                new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "group"),
            };
            action.AttributeRouteInfo          = new AttributeRouteInfo();
            action.AttributeRouteInfo.Template = "{controller}/{action}";

            action.RouteValueDefaults.Add("controller", "Home");
            action.RouteValueDefaults.Add("action", "Index");

            var expectedMessage =
                "The following errors occurred with attribute routing information:" + Environment.NewLine +
                Environment.NewLine +
                "For action: 'Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index'" + Environment.NewLine +
                "Error: The attribute route '{controller}/{action}' cannot contain a parameter named '{controller}'. " +
                "Use '[controller]' in the route template to insert the value 'Home'.";

            var handler  = CreateRouter();
            var services = CreateServices(action);

            var route = AttributeRouting.CreateAttributeMegaRoute(handler, services);

            // Act & Assert
            var ex = await Assert.ThrowsAsync <InvalidOperationException>(async() =>
            {
                await route.RouteAsync(new RouteContext(new DefaultHttpContext()));
            });

            Assert.Equal(expectedMessage, ex.Message);
        }
        public ControllerActionInvoker(
            [NotNull] ActionContext actionContext,
            [NotNull] IReadOnlyList <IFilterProvider> filterProviders,
            [NotNull] IControllerFactory controllerFactory,
            [NotNull] ControllerActionDescriptor descriptor,
            [NotNull] IReadOnlyList <IInputFormatter> inputFormatters,
            [NotNull] IReadOnlyList <IOutputFormatter> outputFormatters,
            [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder,
            [NotNull] IReadOnlyList <IModelBinder> modelBinders,
            [NotNull] IReadOnlyList <IModelValidatorProvider> modelValidatorProviders,
            [NotNull] IReadOnlyList <IValueProviderFactory> valueProviderFactories,
            [NotNull] IScopedInstance <ActionBindingContext> actionBindingContextAccessor,
            [NotNull] ITempDataDictionary tempData,
            [NotNull] ILoggerFactory loggerFactory,
            int maxModelValidationErrors)
            : base(
                actionContext,
                filterProviders,
                inputFormatters,
                outputFormatters,
                modelBinders,
                modelValidatorProviders,
                valueProviderFactories,
                actionBindingContextAccessor,
                loggerFactory,
                maxModelValidationErrors)
        {
            _descriptor        = descriptor;
            _controllerFactory = controllerFactory;
            _argumentBinder    = controllerActionArgumentBinder;
            _tempData          = tempData;

            if (descriptor.MethodInfo == null)
            {
                throw new ArgumentException(
                          Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo",
                                                                     typeof(ControllerActionDescriptor)),
                          "descriptor");
            }
        }
示例#27
0
        private static string CreateMixedRoutedActionDescriptorsErrorMessage(
            ControllerActionDescriptor actionDescriptor,
            IDictionary <ActionModel, IList <ControllerActionDescriptor> > actionsForMethod)
        {
            // Text to show as the attribute route template for conventionally routed actions.
            var nullTemplate = Resources.AttributeRoute_NullTemplateRepresentation;

            var actionDescriptions = new List <string>();

            foreach (var action in actionsForMethod.SelectMany(kvp => kvp.Value))
            {
                var routeTemplate = action.AttributeRouteInfo?.Template ?? nullTemplate;

                var verbs          = action.ActionConstraints.OfType <HttpMethodActionConstraint>().FirstOrDefault()?.HttpMethods;
                var formattedVerbs = string.Join(", ", verbs.OrderBy(v => v, StringComparer.Ordinal));

                var description =
                    Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod_Item(
                        action.DisplayName,
                        routeTemplate,
                        formattedVerbs);

                actionDescriptions.Add(description);
            }

            // Sample error message:
            //
            // A method 'MyApplication.CustomerController.Index' must not define attributed actions and
            // non attributed actions at the same time:
            // Action: 'MyApplication.CustomerController.Index' - Route Template: 'Products' - HTTP Verbs: 'PUT'
            // Action: 'MyApplication.CustomerController.Index' - Route Template: '(none)' - HTTP Verbs: 'POST'
            //
            // Use 'AcceptVerbsAttribute' to create a single route that allows multiple HTTP verbs and defines a route,
            // or set a route template in all attributes that constrain HTTP verbs.
            return
                (Resources.FormatAttributeRoute_MixedAttributeAndConventionallyRoutedActions_ForMethod(
                     actionDescriptor.DisplayName,
                     Environment.NewLine,
                     string.Join(Environment.NewLine, actionDescriptions)));
        }
        public ControllerActionInvoker(
            [NotNull] ActionContext actionContext,
            [NotNull] IReadOnlyList<IFilterProvider> filterProviders,
            [NotNull] IControllerFactory controllerFactory,
            [NotNull] ControllerActionDescriptor descriptor,
            [NotNull] IReadOnlyList<IInputFormatter> inputFormatters,
            [NotNull] IReadOnlyList<IOutputFormatter> outputFormatters,
            [NotNull] IControllerActionArgumentBinder controllerActionArgumentBinder,
            [NotNull] IReadOnlyList<IModelBinder> modelBinders,
            [NotNull] IReadOnlyList<IModelValidatorProvider> modelValidatorProviders,
            [NotNull] IReadOnlyList<IValueProviderFactory> valueProviderFactories,
            [NotNull] IActionBindingContextAccessor actionBindingContextAccessor,
            [NotNull] ILogger logger,
            [NotNull] INotifier notifier,
            int maxModelValidationErrors)
            : base(
                  actionContext,
                  filterProviders,
                  inputFormatters,
                  outputFormatters,
                  modelBinders,
                  modelValidatorProviders,
                  valueProviderFactories,
                  actionBindingContextAccessor,
                  logger,
                  notifier,
                  maxModelValidationErrors)
        {
            _descriptor = descriptor;
            _controllerFactory = controllerFactory;
            _argumentBinder = controllerActionArgumentBinder;

            if (descriptor.MethodInfo == null)
            {
                throw new ArgumentException(
                    Resources.FormatPropertyOfTypeCannotBeNull("MethodInfo",
                                                               typeof(ControllerActionDescriptor)),
                    "descriptor");
            }
        }
        /// <summary>
        /// Initializes a new instance of the WebApiActionDescriptor class.
        /// </summary>
        /// <param name="actionDescriptor">The inner descriptor.</param>
        public WebApiActionDescriptor(ControllerActionDescriptor actionDescriptor)
        {
            if (actionDescriptor == null)
            {
                throw Error.ArgumentNull("actionDescriptor");
            }

            this.innerDescriptor      = actionDescriptor;
            this.supportedHttpMethods = new List <ODataRequestMethod>();

            // Determine the supported methods.
            IEnumerable <string> actionMethods = null; /*actionDescriptor.ActionConstraints?
                                                        * .OfType<HttpMethodActionConstraint>()
                                                        * .FirstOrDefault()?
                                                        * .HttpMethods;
                                                        */

            if (actionMethods == null)
            {
                // If no HttpMethodActionConstraint is specified, fall back to convention the way AspNet does.
                actionMethods = SupportedHttpMethodConventions
                                .Where(method => actionDescriptor.MethodInfo.Name.StartsWith(method, StringComparison.OrdinalIgnoreCase));

                // Use POST as the default method.
                if (!actionMethods.Any())
                {
                    actionMethods = new string[] { "POST" };
                }
            }

            foreach (string method in actionMethods)
            {
                bool ignoreCase = true;
                ODataRequestMethod methodEnum = ODataRequestMethod.Unknown;
                if (Enum.TryParse <ODataRequestMethod>(method, ignoreCase, out methodEnum))
                {
                    this.supportedHttpMethods.Add(methodEnum);
                }
            }
        }
示例#30
0
        private string GetOperationId(OpenApiDocument document, ControllerActionDescriptor actionDescriptor, MethodInfo method)
        {
            string operationId;

            dynamic swaggerOperationAttribute = method
                                                .GetCustomAttributes()
                                                .FirstAssignableToTypeNameOrDefault("SwaggerOperationAttribute", TypeNameStyle.Name);

            if (swaggerOperationAttribute != null && !string.IsNullOrEmpty(swaggerOperationAttribute.OperationId))
            {
                operationId = swaggerOperationAttribute.OperationId;
            }
            else if (Settings.UseRouteNameAsOperationId && !string.IsNullOrEmpty(actionDescriptor.AttributeRouteInfo.Name))
            {
                operationId = actionDescriptor.AttributeRouteInfo.Name;
            }
            else
            {
                dynamic openApiControllerAttribute = actionDescriptor
                                                     .ControllerTypeInfo?
                                                     .GetCustomAttributes()?
                                                     .FirstAssignableToTypeNameOrDefault("OpenApiControllerAttribute", TypeNameStyle.Name);

                var controllerName =
                    openApiControllerAttribute != null && !string.IsNullOrEmpty(openApiControllerAttribute.Name) ?
                    openApiControllerAttribute.Name :
                    actionDescriptor.ControllerName;

                operationId = controllerName + "_" + GetActionName(actionDescriptor.ActionName);
            }

            var number = 1;

            while (document.Operations.Any(o => o.Operation.OperationId == operationId + (number > 1 ? "_" + number : string.Empty)))
            {
                number++;
            }

            return(operationId + (number > 1 ? number.ToString() : string.Empty));
        }
示例#31
0
        public void OnAuthorization(AuthorizationFilterContext filterContext)
        {
            ////验证是否是登录用户
            ControllerActionDescriptor actionDescriptor = null;
            var identity = filterContext.HttpContext.User.Identity;

            if (identity.IsAuthenticated)
            {
                actionDescriptor = (ControllerActionDescriptor)filterContext.ActionDescriptor;
                var controllerName = actionDescriptor.ControllerName;
                var actionName     = actionDescriptor.ActionName;

                //验证用户操作是否在权限列表中
                if (HasActionQulification(actionName, controllerName, identity.Name))
                {
                    if (string.IsNullOrEmpty(UserLoginTicket))
                    {
                        //用户的Session, Cookie都过期,需要重新登录
                        filterContext.HttpContext.Response.Redirect("~/Account/Login", false);
                    }
                    else
                    {
                        //虽然是登录用户,但没有该Action的权限,跳转到“未授权访问”页面
                        filterContext.HttpContext.Response.Redirect("~/Home/UnAuthorized", true);
                    }
                }
            }
            else
            {
                //未登录用户,则判断是否是匿名访问
                var  actionAttributes = actionDescriptor.MethodInfo.GetCustomAttributes(inherit: true);
                bool isAnonymous      = actionAttributes.Any(a => a is AllowAnonymousFilter);

                if (!isAnonymous)
                {
                    //未验证(登录)的用户, 而且是非匿名访问,则转向登录页面
                    filterContext.HttpContext.Response.Redirect("~/Account/Login", true);
                }
            }
        }
        private ControllerActionDescriptor CreateActionDescriptor(
            string httpMethod, string routeTemplate, string actionFixtureName)
        {
            var descriptor = new ControllerActionDescriptor();

            descriptor.SetProperty(new ApiDescriptionActionData());
            descriptor.DisplayName = actionFixtureName;

            descriptor.ActionConstraints = new List <IActionConstraintMetadata>
            {
                new HttpMethodConstraint(new[] { httpMethod })
            };
            descriptor.AttributeRouteInfo = new AttributeRouteInfo {
                Template = routeTemplate
            };

            descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName);
            if (descriptor.MethodInfo == null)
            {
                throw new InvalidOperationException(
                          string.Format("{0} is not declared in ActionFixtures", actionFixtureName));
            }

            descriptor.Parameters = descriptor.MethodInfo.GetParameters()
                                    .Select(paramInfo => new ParameterDescriptor
            {
                Name          = paramInfo.Name,
                ParameterType = paramInfo.ParameterType,
                BindingInfo   = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false))
            })
                                    .ToList();

            // Set some additional properties - typically done via IApplicationModelConvention
            var attributes = descriptor.MethodInfo.GetCustomAttributes(true);

            descriptor.Properties.Add("ActionAttributes", attributes);
            descriptor.Properties.Add("IsObsolete", attributes.OfType <ObsoleteAttribute>().Any());

            return(descriptor);
        }
        public void TransformAsyncReturnsCorrectRouteValues()
        {
            // Arrange
            IEndpointRouteBuilder builder = EndpointRouteBuilderFactory.Create("odata",
                                                                               c => c.AddService(ServiceLifetime.Singleton, b => GetEdmModel()));

            HttpContext httpContext = new DefaultHttpContext
            {
                RequestServices = builder.ServiceProvider
            };

            HttpRequest          request = SetHttpRequest(httpContext, HttpMethod.Get, "http://localhost:123/Customers(1)");
            RouteValueDictionary values  = new RouteValueDictionary();

            values.Add("ODataEndpointPath_odata", "Customers(1)");

            ActionDescriptor actionDescriptor = new ControllerActionDescriptor
            {
                ControllerName = "Customers",
                ActionName     = "Get"
            };
            IActionSelector actionSelector = new MockActionSelector(actionDescriptor);

            // Act
            ODataEndpointRouteValueTransformer transformer = new ODataEndpointRouteValueTransformer(actionSelector);
            ValueTask <RouteValueDictionary>   actual      = transformer.TransformAsync(httpContext, values);

            // Assert
            Assert.NotNull(actual.Result);
            RouteValueDictionary routeValues = actual.Result;

            Assert.Equal(4, routeValues.Count);
            Assert.Equal("Customers(1)", routeValues["ODataEndpointPath_odata"]);
            Assert.Equal("Customers", routeValues["controller"]);
            Assert.Equal("Get", routeValues["action"]);
            Assert.Equal("Customers(1)", routeValues["odataPath"]);

            Assert.NotNull(httpContext.ODataFeature().Path);
            Assert.Same(actionDescriptor, httpContext.ODataFeature().ActionDescriptor);
        }
        public static void AddRouteValues(
            ControllerActionDescriptor actionDescriptor,
            ControllerModel controller,
            ActionModel action)
        {
            // Apply all the constraints defined on the action, then controller (for example, [Area])
            // to the actions. Also keep track of all the constraints that require preventing actions
            // without the constraint to match. For example, actions without an [Area] attribute on their
            // controller should not match when a value has been given for area when matching a url or
            // generating a link.
            foreach (var kvp in action.RouteValues)
            {
                // Skip duplicates
                if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key))
                {
                    actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value);
                }
            }

            foreach (var kvp in controller.RouteValues)
            {
                // Skip duplicates - this also means that a value on the action will take precedence
                if (!actionDescriptor.RouteValues.ContainsKey(kvp.Key))
                {
                    actionDescriptor.RouteValues.Add(kvp.Key, kvp.Value);
                }
            }

            // Lastly add the 'default' values
            if (!actionDescriptor.RouteValues.ContainsKey("action"))
            {
                actionDescriptor.RouteValues.Add("action", action.ActionName ?? string.Empty);
            }

            if (!actionDescriptor.RouteValues.ContainsKey("controller"))
            {
                actionDescriptor.RouteValues.Add("controller", controller.ControllerName);
            }
        }
示例#35
0
        private List <string> getAuthTypes(ControllerActionDescriptor ad)
        {
            var authenticationSchemes = new List <string>();

            if (ad.MethodInfo.IsDefined(typeof(AuthorizeAttribute), false))
            {
                var authorizeAttr = ad.MethodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;
                if (authorizeAttr != null)
                {
                    authenticationSchemes = authorizeAttr.AuthenticationSchemes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                }
            }
            else if (ad.ControllerTypeInfo.IsDefined(typeof(AuthorizeAttribute), false))
            {
                var authorizeAttr = ad.ControllerTypeInfo.GetCustomAttributes(typeof(AuthorizeAttribute), false).FirstOrDefault() as AuthorizeAttribute;
                if (authorizeAttr != null)
                {
                    authenticationSchemes = authorizeAttr.AuthenticationSchemes.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                }
            }
            return(authenticationSchemes);
        }
示例#36
0
        private IDictionary <string, object> GetActionParameters(ControllerActionDescriptor actionDescriptor, IDictionary <string, object> actionArguments, bool serializeParams)
        {
            var args = actionArguments.ToDictionary(k => k.Key, v => v.Value);

            foreach (var param in actionDescriptor.Parameters)
            {
                var paramDescriptor = param as ControllerParameterDescriptor;
                if (paramDescriptor?.ParameterInfo.GetCustomAttribute <AuditIgnoreAttribute>(true) != null)
                {
                    args.Remove(param.Name);
                }
                else if (paramDescriptor?.ParameterInfo.GetCustomAttribute <FromServicesAttribute>(true) != null)
                {
                    args.Remove(param.Name);
                }
            }
            if (serializeParams)
            {
                return(AuditApiHelper.SerializeParameters(args));
            }
            return(args);
        }
        private ControllerActionDescriptor CreateActionDescriptor(
            string httpMethod,
            string routeTemplate,
            string actionFixtureName,
            string controllerFixtureName
        )
        {
            var descriptor = new ControllerActionDescriptor();
            descriptor.SetProperty(new ApiDescriptionActionData());
            descriptor.DisplayName = actionFixtureName;

            descriptor.ActionConstraints = new List<IActionConstraintMetadata>();
            if (httpMethod != null)
                descriptor.ActionConstraints.Add(new HttpMethodConstraint(new[] { httpMethod }));

            descriptor.AttributeRouteInfo = new AttributeRouteInfo { Template = routeTemplate };

            descriptor.MethodInfo = typeof(ActionFixtures).GetMethod(actionFixtureName);
            if (descriptor.MethodInfo == null)
                throw new InvalidOperationException(
                    string.Format("{0} is not declared in ActionFixtures", actionFixtureName));

            descriptor.Parameters = descriptor.MethodInfo.GetParameters()
                .Select(paramInfo => new ParameterDescriptor
                    {
                        Name = paramInfo.Name,
                        ParameterType = paramInfo.ParameterType,
                        BindingInfo = BindingInfo.GetBindingInfo(paramInfo.GetCustomAttributes(false))
                    })
                .ToList();

            var controllerType = typeof(ControllerFixtures).GetNestedType(controllerFixtureName);
            if (controllerType == null)
                throw new InvalidOperationException(
                    string.Format("{0} is not declared in ControllerFixtures", controllerFixtureName));
            descriptor.ControllerTypeInfo = controllerType.GetTypeInfo();

            return descriptor;
        }
        public void CreateController_SetsPropertiesFromActionContextHierarchy()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
            };
            var services = GetServices();
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act
            var result = factory.CreateController(context);

            // Assert
            var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
            Assert.Same(context, controller.ActionContext);
            Assert.Same(httpContext, controller.HttpContext);
        }
        public void CreateController_ThrowsIfPropertyCannotBeActivated()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerThatCannotBeActivated).GetTypeInfo()
            };
            var services = GetServices();
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act and Assert
            var exception = Assert.Throws<InvalidOperationException>(() => factory.CreateController(context));
            Assert.Equal("The property 'Service' on controller '" + typeof(ControllerThatCannotBeActivated) +
                        "' cannot be activated.", exception.Message);
        }
        public void CreateController_SetsBindingContext()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
            };
            var bindingContext = new ActionBindingContext();

            var services = GetServices();
            services.GetRequiredService<IScopedInstance<ActionBindingContext>>().Value = bindingContext;
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act
            var result = factory.CreateController(context);

            // Assert
            var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
            Assert.Same(bindingContext, controller.BindingContext);
        }
        private ControllerActionDescriptor CreateActionDescriptor(string methodName = null, Type controllerType = null)
        {
            var action = new ControllerActionDescriptor();
            action.SetProperty(new ApiDescriptionActionData());

            if (controllerType != null)
            {
                action.MethodInfo = controllerType.GetMethod(
                    methodName ?? "ReturnsObject",
                    BindingFlags.Instance | BindingFlags.Public);

                action.ControllerTypeInfo = controllerType.GetTypeInfo();
                action.BoundProperties = new List<ParameterDescriptor>();

                foreach (var property in action.ControllerTypeInfo.GetProperties())
                {
                    var bindingInfo = BindingInfo.GetBindingInfo(property.GetCustomAttributes().OfType<object>());
                    if (bindingInfo != null)
                    {
                        action.BoundProperties.Add(new ParameterDescriptor()
                        {
                            BindingInfo = bindingInfo,
                            Name = property.Name,
                            ParameterType = property.PropertyType,
                        });
                    }
                }
            }
            else
            {
                action.MethodInfo = GetType().GetMethod(
                    methodName ?? "ReturnsObject",
                    BindingFlags.Instance | BindingFlags.NonPublic);
            }

            action.Parameters = new List<ParameterDescriptor>();
            foreach (var parameter in action.MethodInfo.GetParameters())
            {
                action.Parameters.Add(new ParameterDescriptor()
                {
                    Name = parameter.Name,
                    ParameterType = parameter.ParameterType,
                    BindingInfo = BindingInfo.GetBindingInfo(parameter.GetCustomAttributes().OfType<object>())
                });
            }

            return action;
        }
        public void AttributeRouting_WithControllerActionDescriptor()
        {
            // Arrange
            var controllerType = typeof(HomeController);
            var actionMethod = controllerType.GetMethod("Index");

            var action = new ControllerActionDescriptor();
            action.DisplayName = "Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index";
            action.MethodInfo = actionMethod;
            action.RouteConstraints = new List<RouteDataActionConstraint>()
            {
                new RouteDataActionConstraint(AttributeRouting.RouteGroupKey, "group"),
            };
            action.AttributeRouteInfo = new AttributeRouteInfo();
            action.AttributeRouteInfo.Template = "{controller}/{action}";

            action.RouteValueDefaults.Add("controller", "Home");
            action.RouteValueDefaults.Add("action", "Index");

            var expectedMessage =
                "The following errors occurred with attribute routing information:" + Environment.NewLine +
                Environment.NewLine +
                "For action: 'Microsoft.AspNet.Mvc.Routing.AttributeRoutingTest+HomeController.Index'" + Environment.NewLine +
                "Error: The attribute route '{controller}/{action}' cannot contain a parameter named '{controller}'. " +
                "Use '[controller]' in the route template to insert the value 'Home'.";

            var handler = CreateRouter();
            var services = CreateServices(action);

            // Act & Assert
            var ex = Assert.Throws<InvalidOperationException>(() =>
            {
				AttributeRouting.CreateAttributeMegaRoute(handler, services);
			});

            Assert.Equal(expectedMessage, ex.Message);
        }
        public void CreateController_IgnoresPropertiesThatAreNotDecoratedWithActivateAttribute()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor
            {
                ControllerTypeInfo = typeof(ControllerWithActivateAndFromServices).GetTypeInfo()
            };
            var services = GetServices();
            var httpContext = new DefaultHttpContext
            {
                RequestServices = services
            };
            var context = new ActionContext(httpContext, new RouteData(), actionDescriptor);
            var factory = new DefaultControllerFactory(new DefaultControllerActivator(new DefaultTypeActivatorCache()));

            // Act
            var result = factory.CreateController(context);

            // Assert
            var controller = Assert.IsType<ControllerWithActivateAndFromServices>(result);
            Assert.Null(controller.Response);
        }
        public void ControllerContextSetter_CanBeUsedWithControllerActionContext()
        {
            // Arrange
            var actionDescriptor = new ControllerActionDescriptor();
            var httpContext = new DefaultHttpContext();
            var routeData = new RouteData();

            var controllerContext = new ControllerContext()
            {
                ActionDescriptor = actionDescriptor,
                HttpContext = httpContext,
                RouteData = routeData,
            };

            var controller = new TestabilityController();

            // Act
            controller.ControllerContext = controllerContext;

            // Assert
            Assert.Same(httpContext, controller.HttpContext);
            Assert.Same(routeData, controller.RouteData);
            Assert.Equal(controllerContext.ModelState, controller.ModelState);
            Assert.Same(actionDescriptor, controllerContext.ActionDescriptor);
        }