internal static IReadOnlyCollection<RouteEntry> MapAttributeRoutes(
     ReflectedAsyncControllerDescriptor controller)
 {
     SubRouteCollection collector = new SubRouteCollection();
     AddRouteEntries(collector, controller, new DefaultInlineConstraintResolver());
     return collector.Entries;
 }
示例#2
0
 private static RoutePrefixAttribute GetPrefixFrom(ReflectedAsyncControllerDescriptor controllerDescriptor)
 {
     // this only happens once per controller type, for the lifetime of the application,
     // so we do not need to cache the results
     return(controllerDescriptor.GetCustomAttributes(typeof(RoutePrefixAttribute), inherit: false)
            .Cast <RoutePrefixAttribute>().SingleOrDefault());
 }
        internal IReadOnlyCollection <RouteEntry> MapAttributeRoutes(ReflectedAsyncControllerDescriptor controller)
        {
            SubRouteCollection collector = new SubRouteCollection();

            AddRouteEntries(collector, controller);
            return(collector.Entries);
        }
示例#4
0
        /// <summary>
        /// Resolves the action method parameters.
        /// </summary>
        /// <param name="controllerTypeResolver">The controller type resolver.</param>
        /// <param name="areaName">Name of the area.</param>
        /// <param name="controllerName">Name of the controller.</param>
        /// <param name="actionMethodName">Name of the action method.</param>
        /// <returns>
        /// A action method parameters represented as a <see cref="string"/> instance
        /// </returns>
        public IEnumerable <string> ResolveActionMethodParameters(IControllerTypeResolver controllerTypeResolver,
                                                                  string areaName, string controllerName,
                                                                  string actionMethodName)
        {
            // Is the request cached?
            string cacheKey = areaName + "_" + controllerName + "_" + actionMethodName;

            if (Cache.ContainsKey(cacheKey))
            {
                return(Cache[cacheKey]);
            }

            // Get controller type
            Type controllerType = controllerTypeResolver.ResolveControllerType(areaName, controllerName);

            // Get action method information
            var actionParameters = new List <string>();

            if (controllerType != null)
            {
                ControllerDescriptor controllerDescriptor = null;
                if (typeof(IController).IsAssignableFrom(controllerType))
                {
                    controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
                }
                else if (typeof(IAsyncController).IsAssignableFrom(controllerType))
                {
                    controllerDescriptor = new ReflectedAsyncControllerDescriptor(controllerType);
                }

                ActionDescriptor[] actionDescriptors = controllerDescriptor.GetCanonicalActions()
                                                       .Where(a => a.ActionName == actionMethodName).ToArray();

                if (actionDescriptors != null && actionDescriptors.Length > 0)
                {
                    foreach (ActionDescriptor actionDescriptor in actionDescriptors)
                    {
                        actionParameters.AddRange(actionDescriptor.GetParameters().Select(p => p.ParameterName));
                    }
                }
            }

            // Cache the result
            if (!Cache.ContainsKey(cacheKey))
            {
                try
                {
                    Cache.Add(cacheKey, actionParameters);
                }
                catch (ArgumentException)
                {
                    // Nomnomnom... We're intentionally eating it here
                }
            }

            // Return
            return(actionParameters);
        }
示例#5
0
        private static RouteAreaAttribute GetAreaFrom(ReflectedAsyncControllerDescriptor controllerDescriptor)
        {
            RouteAreaAttribute areaAttribute =
                controllerDescriptor.GetCustomAttributes(typeof(RouteAreaAttribute), true)
                .Cast <RouteAreaAttribute>()
                .FirstOrDefault();

            return(areaAttribute);
        }
示例#6
0
        internal List <RouteEntry> MapMvcAttributeRoutes(ReflectedAsyncControllerDescriptor controllerDescriptor)
        {
            RoutePrefixAttribute prefixAttribute = GetPrefixFrom(controllerDescriptor);

            ValidatePrefixTemplate(prefixAttribute, controllerDescriptor);

            RouteAreaAttribute area       = GetAreaFrom(controllerDescriptor);
            string             areaName   = GetAreaName(controllerDescriptor, area);
            string             areaPrefix = area != null ? area.AreaPrefix ?? area.AreaName : null;

            ValidateAreaPrefixTemplate(areaPrefix, areaName, controllerDescriptor);

            string controllerName = controllerDescriptor.ControllerName;

            AsyncActionMethodSelector actionSelector    = controllerDescriptor.Selector;
            IEnumerable <MethodInfo>  actionMethodsInfo = actionSelector.AliasedMethods
                                                          .Concat(actionSelector.NonAliasedMethods.SelectMany(x => x))
                                                          .Where(m => m.DeclaringType == controllerDescriptor.ControllerType);

            if (actionSelector.AllowLegacyAsyncActions)
            {
                // if the ActionAsync / ActionCompleted pattern is used, we need to remove the "Completed" methods
                // and not look up routing attributes on them
                actionMethodsInfo =
                    actionMethodsInfo.Where(m => !m.Name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase));
            }

            List <RouteEntry> routeEntries = new List <RouteEntry>();

            foreach (var method in actionMethodsInfo)
            {
                string actionName = GetCanonicalActionName(method, actionSelector.AllowLegacyAsyncActions);
                IEnumerable <IDirectRouteInfoProvider> routeAttributes = GetRouteAttributes(method);

                foreach (var routeAttribute in routeAttributes)
                {
                    ValidateTemplate(routeAttribute, actionName, controllerDescriptor);

                    string prefix = prefixAttribute != null ? prefixAttribute.Prefix : null;

                    string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.RouteTemplate);
                    Route  route    = _routeBuilder.BuildDirectRoute(template, routeAttribute.Verbs, controllerName,
                                                                     actionName, method, areaName);
                    RouteEntry entry = new RouteEntry
                    {
                        Name          = routeAttribute.RouteName ?? template,
                        Route         = route,
                        RouteTemplate = template,
                        ParsedRoute   = RouteParser.Parse(route.Url),
                        Order         = routeAttribute.RouteOrder
                    };
                    routeEntries.Add(entry);
                }
            }

            return(routeEntries);
        }
        public void FindActionThrowsIfControllerContextIsNull()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            Assert.ThrowsArgumentNull(
                delegate { cd.FindAction(null, "someName"); }, "controllerContext");
        }
        public void FindActionThrowsIfActionNameIsNull()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            Assert.ThrowsArgumentNullOrEmpty(
                delegate { cd.FindAction(new Mock<ControllerContext>().Object, null); }, "actionName");
        }
        public void ConstructorSetsControllerTypeProperty() {
            // Arrange
            Type controllerType = typeof(string);

            // Act
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Assert
            Assert.AreSame(controllerType, cd.ControllerType);
        }
        public void FindActionThrowsIfActionNameIsNull()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            Assert.ThrowsArgumentNullOrEmpty(
                delegate { cd.FindAction(new Mock <ControllerContext>().Object, null); }, "actionName");
        }
示例#11
0
        public void MapMvcAttributeRoutes_DoesNotTryToInferRouteNames()
        {
            var controllerDescriptor = new ReflectedAsyncControllerDescriptor(typeof(MyController));
            var mapper = new AttributeRoutingMapper(new RouteBuilder());

            var routeEntries = mapper.MapMvcAttributeRoutes(controllerDescriptor);

            var routeEntry = Assert.Single(routeEntries);

            Assert.Null(routeEntry.Name);
        }
        public void FindActionThrowsIfActionNameIsEmpty() {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            ExceptionHelper.ExpectArgumentExceptionNullOrEmpty(
                delegate {
                    cd.FindAction(new Mock<ControllerContext>().Object, "");
                }, "actionName");
        }
        public void ConstructorSetsControllerTypeProperty()
        {
            // Arrange
            Type controllerType = typeof(string);

            // Act
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Assert
            Assert.AreSame(controllerType, cd.ControllerType);
        }
示例#14
0
        public void MapMvcAttributeRoutes_RespectsActionNameAttribute()
        {
            var controllerDescriptor = new ReflectedAsyncControllerDescriptor(typeof(MyController));
            var mapper = new AttributeRoutingMapper(new RouteBuilder());

            var routeEntries = mapper.MapMvcAttributeRoutes(controllerDescriptor);

            var routeEntry = Assert.Single(routeEntries);

            Assert.Equal("ActionName", routeEntry.Route.Defaults["action"]);
        }
        public void FindActionReturnsNullIfNoActionFound() {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock<ControllerContext>().Object, "NonExistent");

            // Assert
            Assert.IsNull(ad);
        }
        public void FindActionReturnsNullIfNoActionFound()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock <ControllerContext>().Object, "NonExistent");

            // Assert
            Assert.IsNull(ad);
        }
示例#17
0
        public void MapMvcAttributeRoutes_WithControllerRoute_AndNoReachableActions()
        {
            // Arrange
            var controllerDescriptor = new ReflectedAsyncControllerDescriptor(typeof(NoActionsController));
            var mapper = new AttributeRoutingMapper(new RouteBuilder2());

            // Act
            var entries = mapper.MapMvcAttributeRoutes(controllerDescriptor);

            // Assert
            Assert.Empty(entries);
        }
        public void FindActionThrowsIfActionNameIsEmpty()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            ExceptionHelper.ExpectArgumentExceptionNullOrEmpty(
                delegate {
                cd.FindAction(new Mock <ControllerContext>().Object, "");
            }, "actionName");
        }
        public void IsDefinedCallsTypeIsDefined()
        {
            // Arrange
            Mock <Type> mockType = new Mock <Type>();

            mockType.Expect(t => t.IsDefined(typeof(ObsoleteAttribute), true)).Returns(true);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            bool isDefined = cd.IsDefined(typeof(ObsoleteAttribute), true);

            // Assert
            Assert.IsTrue(isDefined);
        }
        public void GetCanonicalActionsReturnsEmptyArray()
        {
            // this method does nothing by default

            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor[] canonicalActions = cd.GetCanonicalActions();

            // Assert
            Assert.AreEqual(0, canonicalActions.Length);
        }
        public ControllerDescriptor Create(Type controllerType)
        {
            ControllerDescriptor controllerDescriptor = null;

            if (typeof(IController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
            }
            else if (typeof(IAsyncController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedAsyncControllerDescriptor(controllerType);
            }
            return(controllerDescriptor);
        }
        public void GetCustomAttributesCallsTypeGetCustomAttributes()
        {
            // Arrange
            object[]    expected = new object[0];
            Mock <Type> mockType = new Mock <Type>();

            mockType.Setup(t => t.GetCustomAttributes(true)).Returns(expected);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            object[] returned = cd.GetCustomAttributes(true);

            // Assert
            Assert.Same(expected, returned);
        }
        public static void AddDirectRouteFromMethod <T>(SubRouteCollection collector, Expression <Action <T> > methodCall)
        {
            var method     = ((MethodCallExpression)methodCall.Body).Method;
            var attributes = method.GetCustomAttributes(false).OfType <IRouteInfoProvider>();

            var controllerDescriptor = new ReflectedAsyncControllerDescriptor(method.DeclaringType);
            var actionDescriptor     = new ReflectedActionDescriptor(method, method.Name, controllerDescriptor);

            foreach (var attribute in attributes)
            {
                var subRoute = new Route(attribute.Template, routeHandler: null);
                subRoute.SetTargetActionDescriptors(new ActionDescriptor[] { actionDescriptor });
                collector.Add(new RouteEntry(null, subRoute));
            }
        }
        public void GetCustomAttributesWithAttributeTypeCallsTypeGetCustomAttributes()
        {
            // Arrange
            object[]    expected = new object[0];
            Mock <Type> mockType = new Mock <Type>();

            mockType.Expect(t => t.GetCustomAttributes(typeof(ObsoleteAttribute), true)).Returns(expected);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            object[] returned = cd.GetCustomAttributes(typeof(ObsoleteAttribute), true);

            // Assert
            Assert.AreSame(expected, returned);
        }
示例#25
0
        private static string GetPrefixFrom(ReflectedAsyncControllerDescriptor controllerDescriptor)
        {
            // this only happens once per controller type, for the lifetime of the application,
            // so we do not need to cache the results
            object[] routePrefixAttributes = controllerDescriptor.GetCustomAttributes(typeof(RoutePrefixAttribute), inherit: false);
            if (routePrefixAttributes.Length > 0)
            {
                RoutePrefixAttribute routePrefixAttribute = routePrefixAttributes[0] as RoutePrefixAttribute;
                if (routePrefixAttribute != null)
                {
                    return(routePrefixAttribute.Prefix);
                }
            }

            return(null);
        }
示例#26
0
        private static string GetAreaName(ReflectedAsyncControllerDescriptor controllerDescriptor, RouteAreaAttribute area)
        {
            if (area == null)
            {
                return(null);
            }

            if (area.AreaName != null)
            {
                return(area.AreaName);
            }
            if (controllerDescriptor.ControllerType.Namespace != null)
            {
                return(controllerDescriptor.ControllerType.Namespace.Split('.').Last());
            }

            throw Error.InvalidOperation(MvcResources.AttributeRouting_CouldNotInferAreaNameFromMissingNamespace, controllerDescriptor.ControllerName);
        }
        public void FindActionReturnsActionDescriptorIfFound()
        {
            // Arrange
            Type       controllerType             = typeof(MyController);
            MethodInfo asyncMethodInfo            = controllerType.GetMethod("FooAsync");
            MethodInfo completedMethodInfo        = controllerType.GetMethod("FooCompleted");
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock <ControllerContext>().Object, "NewName");

            // Assert
            Assert.Equal("NewName", ad.ActionName);
            var castAd = Assert.IsType <ReflectedAsyncActionDescriptor>(ad);

            Assert.Same(asyncMethodInfo, castAd.AsyncMethodInfo);
            Assert.Same(completedMethodInfo, castAd.CompletedMethodInfo);
            Assert.Same(cd, ad.ControllerDescriptor);
        }
        public void FindActionReturnsActionDescriptorIfFound() {
            // Arrange
            Type controllerType = typeof(MyController);
            MethodInfo asyncMethodInfo = controllerType.GetMethod("FooAsync");
            MethodInfo completedMethodInfo = controllerType.GetMethod("FooCompleted");
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock<ControllerContext>().Object, "NewName");

            // Assert
            Assert.AreEqual("NewName", ad.ActionName);
            Assert.IsInstanceOfType(ad, typeof(ReflectedAsyncActionDescriptor));
            ReflectedAsyncActionDescriptor castAd = (ReflectedAsyncActionDescriptor)ad;

            Assert.AreSame(asyncMethodInfo, castAd.AsyncMethodInfo, "AsyncMethodInfo pointed to wrong method.");
            Assert.AreSame(completedMethodInfo, castAd.CompletedMethodInfo, "CompletedMethodInfo pointed to wrong method.");
            Assert.AreSame(cd, ad.ControllerDescriptor, "ControllerDescriptor did not point back to correct descriptor.");
        }
        public void FindActionReturnsActionDescriptorIfFound()
        {
            // Arrange
            Type controllerType = typeof(MyController);
            MethodInfo asyncMethodInfo = controllerType.GetMethod("FooAsync");
            MethodInfo completedMethodInfo = controllerType.GetMethod("FooCompleted");
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock<ControllerContext>().Object, "NewName");

            // Assert
            Assert.Equal("NewName", ad.ActionName);
            var castAd = Assert.IsType<ReflectedAsyncActionDescriptor>(ad);

            Assert.Same(asyncMethodInfo, castAd.AsyncMethodInfo);
            Assert.Same(completedMethodInfo, castAd.CompletedMethodInfo);
            Assert.Same(cd, ad.ControllerDescriptor);
        }
示例#30
0
        public void MapMvcAttributeRoutes_WithControllerRoute()
        {
            // Arrange
            var controllerDescriptor = new ReflectedAsyncControllerDescriptor(typeof(AnotherController));
            var mapper = new AttributeRoutingMapper(new RouteBuilder2());

            // Act
            var entries = mapper.MapMvcAttributeRoutes(controllerDescriptor);

            // Assert
            var controllerEntry = Assert.Single(entries.Where(r => !r.Route.Defaults.ContainsKey("action")));

            Assert.Same(controllerDescriptor, controllerEntry.Route.GetTargetControllerDescriptor());

            var actionMethods = controllerEntry.Route.GetTargetActionDescriptors().ToArray();

            Assert.Equal(2, actionMethods.Length);
            Assert.Single(actionMethods, a => a.ActionName == "RegularAction");
            Assert.Single(actionMethods, a => a.ActionName == "AnotherAction");
        }
        public void FindActionReturnsActionDescriptorIfFound()
        {
            // Arrange
            Type       controllerType             = typeof(MyController);
            MethodInfo asyncMethodInfo            = controllerType.GetMethod("FooAsync");
            MethodInfo completedMethodInfo        = controllerType.GetMethod("FooCompleted");
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor ad = cd.FindAction(new Mock <ControllerContext>().Object, "NewName");

            // Assert
            Assert.AreEqual("NewName", ad.ActionName);
            Assert.IsInstanceOfType(ad, typeof(ReflectedAsyncActionDescriptor));
            ReflectedAsyncActionDescriptor castAd = (ReflectedAsyncActionDescriptor)ad;

            Assert.AreSame(asyncMethodInfo, castAd.AsyncMethodInfo, "AsyncMethodInfo pointed to wrong method.");
            Assert.AreSame(completedMethodInfo, castAd.CompletedMethodInfo, "CompletedMethodInfo pointed to wrong method.");
            Assert.AreSame(cd, ad.ControllerDescriptor, "ControllerDescriptor did not point back to correct descriptor.");
        }
示例#32
0
        private static List <ActionDescriptor> GetActionDescriptors(ReflectedAsyncControllerDescriptor controller)
        {
            Contract.Assert(controller != null);

            AsyncActionMethodSelector actionSelector = controller.Selector;

            var actions = new List <ActionDescriptor>();

            foreach (MethodInfo method in actionSelector.ActionMethods)
            {
                string actionName = actionSelector.GetActionName(method);
                ActionDescriptorCreator creator = actionSelector.GetActionDescriptorDelegate(method);
                Debug.Assert(creator != null);

                ActionDescriptor action = creator(actionName, controller);
                actions.Add(action);
            }

            return(actions);
        }
        internal static void AddRouteEntries(SubRouteCollection collector,
            ReflectedAsyncControllerDescriptor controller, IInlineConstraintResolver constraintResolver)
        {
            string prefix = GetRoutePrefix(controller);

            RouteAreaAttribute area = controller.GetAreaFrom();
            string areaName = controller.GetAreaName(area);
            string areaPrefix = area != null ? area.AreaPrefix ?? area.AreaName : null;
            ValidateAreaPrefixTemplate(areaPrefix, areaName, controller);

            AsyncActionMethodSelector actionSelector = controller.Selector;

            foreach (var method in actionSelector.DirectRouteMethods)
            {
                ActionDescriptor action = CreateActionDescriptor(controller, actionSelector, method);

                IEnumerable<IDirectRouteFactory> factories = GetRouteFactories(method, controller.ControllerType);

                AddRouteEntries(collector, areaPrefix, prefix, factories, new ActionDescriptor[] { action },
                    constraintResolver, targetIsAction: true);
            }

            // Check for controller-level routes. 
            List<ActionDescriptor> actionsWithoutRoutes = new List<ActionDescriptor>();

            foreach (var method in actionSelector.StandardRouteMethods)
            {
                ActionDescriptor action = CreateActionDescriptor(controller, actionSelector, method);

                actionsWithoutRoutes.Add(action);
            }

            IReadOnlyCollection<IDirectRouteFactory> controllerFactories = GetRouteFactories(controller);

            // If they exist and have not been overridden, create routes for controller-level route providers.
            if (controllerFactories.Count > 0 && actionsWithoutRoutes.Count > 0)
            {
                AddRouteEntries(collector, areaPrefix, prefix, controllerFactories, actionsWithoutRoutes,
                    constraintResolver, targetIsAction: false);
            }
        }
示例#34
0
        /// <summary>
        /// Determines whether node is accessible to user.
        /// </summary>
        /// <param name="controllerTypeResolver">The controller type resolver.</param>
        /// <param name="provider">The provider.</param>
        /// <param name="context">The context.</param>
        /// <param name="node">The node.</param>
        /// <returns>
        ///     <c>true</c> if accessible to user; otherwise, <c>false</c>.
        /// </returns>
        public bool IsAccessibleToUser(IControllerTypeResolver controllerTypeResolver, DefaultSiteMapProvider provider, HttpContext context, SiteMapNode node)
        {
            // Is security trimming enabled?
            if (!provider.SecurityTrimmingEnabled)
            {
                return(true);
            }

            // Is it an external node?
            var nodeUrl = node.Url;

            if (nodeUrl.StartsWith("http") || nodeUrl.StartsWith("ftp"))
            {
                return(true);
            }

            // Is it a regular node?
            var mvcNode = node as MvcSiteMapNode;

            if (mvcNode == null)
            {
                throw new AclModuleNotSupportedException(
                          Resources.Messages.AclModuleDoesNotSupportRegularSiteMapNodes);
            }

            // Clickable? Always accessible.
            if (mvcNode.Clickable == false)
            {
                return(true);
            }

            // Time to delve into the AuthorizeAttribute defined on the node.
            // Let's start by getting all metadata for the controller...
            var controllerType = controllerTypeResolver.ResolveControllerType(mvcNode.Area, mvcNode.Controller);

            if (controllerType == null)
            {
                return(false);
            }

            // Find routes for the sitemap node's url
            HttpContextBase httpContext    = new HttpContextWrapper(context);
            string          originalPath   = httpContext.Request.Path;
            var             originalRoutes = RouteTable.Routes.GetRouteData(httpContext);

            httpContext.RewritePath(nodeUrl, true);

            HttpContextBase httpContext2 = new HttpContext2(context);
            RouteData       routes       = mvcNode.GetRouteData(httpContext2);

            if (routes == null)
            {
                return(true); // Static URL's will have no route data, therefore return true.
            }
            foreach (var routeValue in mvcNode.RouteValues)
            {
                routes.Values[routeValue.Key] = routeValue.Value;
            }
            if (!routes.Route.Equals(originalRoutes.Route) || originalPath != nodeUrl || mvcNode.Area == String.Empty)
            {
                routes.DataTokens.Remove("area");
                //routes.DataTokens.Remove("Namespaces");
                //routes.Values.Remove("area");
            }
            var requestContext = new RequestContext(httpContext, routes);

            // Create controller context
            var controllerContext = new ControllerContext();

            controllerContext.RequestContext = requestContext;

            // Whether controller is built by the ControllerFactory (or otherwise by Activator)
            bool factoryBuiltController = false;

            try
            {
                string controllerName = requestContext.RouteData.GetRequiredString("controller");
                controllerContext.Controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, controllerName) as ControllerBase;
                factoryBuiltController       = true;
            }
            catch
            {
                try
                {
                    controllerContext.Controller = Activator.CreateInstance(controllerType) as ControllerBase;
                }
                catch
                {
                }
            }

            ControllerDescriptor controllerDescriptor = null;

            if (typeof(IController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
            }
            else if (typeof(IAsyncController).IsAssignableFrom(controllerType))
            {
                controllerDescriptor = new ReflectedAsyncControllerDescriptor(controllerType);
            }

            ActionDescriptor actionDescriptor = null;

            try
            {
                actionDescriptor = controllerDescriptor.FindAction(controllerContext, mvcNode.Action);
            }
            catch
            {
            }
            if (actionDescriptor == null)
            {
                actionDescriptor = controllerDescriptor.GetCanonicalActions().Where(a => a.ActionName == mvcNode.Action).FirstOrDefault();
            }

            // Verify security
            try
            {
                if (actionDescriptor != null)
                {
#if NET35
                    IEnumerable <AuthorizeAttribute> authorizeAttributesToCheck =
                        actionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).OfType
                        <AuthorizeAttribute>().ToList()
                        .Union(
                            controllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).OfType
                            <AuthorizeAttribute>().ToList());
#else
                    IFilterProvider      filterProvider = ResolveFilterProvider();
                    IEnumerable <Filter> filters;

                    // If depencency resolver has an IFilterProvider registered, use it
                    if (filterProvider != null)
                    {
                        filters = filterProvider.GetFilters(controllerContext, actionDescriptor);
                    }
                    // Otherwise use FilterProviders.Providers
                    else
                    {
                        filters = FilterProviders.Providers.GetFilters(controllerContext, actionDescriptor);
                    }

                    IEnumerable <AuthorizeAttribute> authorizeAttributesToCheck =
                        filters
                        .Where(f => typeof(AuthorizeAttribute).IsAssignableFrom(f.Instance.GetType()))
                        .Select(f => f.Instance as AuthorizeAttribute);
#endif

                    // Verify all attributes
                    foreach (var authorizeAttribute in authorizeAttributesToCheck)
                    {
                        try
                        {
                            var currentAuthorizationAttributeType = authorizeAttribute.GetType();

                            var builder             = new AuthorizeAttributeBuilder();
                            var subclassedAttribute =
                                currentAuthorizationAttributeType == typeof(AuthorizeAttribute) ?
                                new InternalAuthorize(authorizeAttribute) :    // No need to use Reflection.Emit when ASP.NET MVC built-in attribute is used
                                (IAuthorizeAttribute)builder.Build(currentAuthorizationAttributeType).Invoke(null);

                            // Copy all properties
                            ObjectCopier.Copy(authorizeAttribute, subclassedAttribute);

                            if (!subclassedAttribute.IsAuthorized(controllerContext.HttpContext))
                            {
                                return(false);
                            }
                        }
                        catch
                        {
                            // do not allow on exception
                            return(false);
                        }
                    }
                }

                // No objection.
                return(true);
            }
            finally
            {
                // Restore HttpContext
                httpContext.RewritePath(originalPath, true);

                // Release controller
                if (factoryBuiltController)
                {
                    ControllerBuilder.Current.GetControllerFactory().ReleaseController(controllerContext.Controller);
                }
            }
        }
        public void IsDefinedCallsTypeIsDefined() {
            // Arrange
            Mock<Type> mockType = new Mock<Type>();
            mockType.Expect(t => t.IsDefined(typeof(ObsoleteAttribute), true)).Returns(true);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            bool isDefined = cd.IsDefined(typeof(ObsoleteAttribute), true);

            // Assert
            Assert.IsTrue(isDefined);
        }
        public void GetCustomAttributesWithAttributeTypeCallsTypeGetCustomAttributes() {
            // Arrange
            object[] expected = new object[0];
            Mock<Type> mockType = new Mock<Type>();
            mockType.Expect(t => t.GetCustomAttributes(typeof(ObsoleteAttribute), true)).Returns(expected);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            object[] returned = cd.GetCustomAttributes(typeof(ObsoleteAttribute), true);

            // Assert
            Assert.AreSame(expected, returned);
        }
        public void GetCanonicalActionsReturnsEmptyArray() {
            // this method does nothing by default

            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act
            ActionDescriptor[] canonicalActions = cd.GetCanonicalActions();

            // Assert
            Assert.AreEqual(0, canonicalActions.Length);
        }
        internal List <RouteEntry> MapMvcAttributeRoutes(ReflectedAsyncControllerDescriptor controllerDescriptor)
        {
            string prefix = controllerDescriptor.GetPrefixFrom();

            ValidatePrefixTemplate(prefix, controllerDescriptor);

            RouteAreaAttribute area       = controllerDescriptor.GetAreaFrom();
            string             areaName   = controllerDescriptor.GetAreaName(area);
            string             areaPrefix = area != null ? area.AreaPrefix ?? area.AreaName : null;

            ValidateAreaPrefixTemplate(areaPrefix, areaName, controllerDescriptor);

            AsyncActionMethodSelector actionSelector    = controllerDescriptor.Selector;
            IEnumerable <MethodInfo>  actionMethodsInfo = actionSelector.DirectRouteMethods;

            List <RouteEntry> routeEntries = new List <RouteEntry>();

            foreach (var method in actionMethodsInfo)
            {
                string actionName = actionSelector.GetActionName(method);
                ActionDescriptorCreator creator = actionSelector.GetActionDescriptorDelegate(method);
                Debug.Assert(creator != null);

                ActionDescriptor actionDescriptor = creator(actionName, controllerDescriptor);

                IEnumerable <IRouteInfoProvider> routeAttributes = GetRouteAttributes(method, controllerDescriptor.ControllerType);

                foreach (var routeAttribute in routeAttributes)
                {
                    ValidateTemplate(routeAttribute.Template, actionName, controllerDescriptor);

                    string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.Template);
                    Route  route    = _routeBuilder.BuildDirectRoute(template, routeAttribute, controllerDescriptor, actionDescriptor);

                    RouteEntry entry = new RouteEntry
                    {
                        Name     = routeAttribute.Name,
                        Route    = route,
                        Template = template,
                    };

                    routeEntries.Add(entry);
                }
            }

            // Check for controller-level routes.
            IEnumerable <IRouteInfoProvider> controllerRouteAttributes = controllerDescriptor.GetDirectRoutes();

            List <ActionDescriptor> actions = new List <ActionDescriptor>();

            foreach (var actionMethod in actionSelector.StandardRouteMethods)
            {
                string actionName = actionSelector.GetActionName(actionMethod);
                ActionDescriptorCreator creator = actionSelector.GetActionDescriptorDelegate(actionMethod);
                Debug.Assert(creator != null);

                ActionDescriptor actionDescriptor = creator(actionName, controllerDescriptor);
                actions.Add(actionDescriptor);
            }

            // Don't create a route for the controller-level attributes if no actions could possibly match
            if (actions.Any())
            {
                foreach (var routeAttribute in controllerRouteAttributes)
                {
                    string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.Template);

                    Route      route = _routeBuilder.BuildDirectRoute(template, routeAttribute, controllerDescriptor, actions);
                    RouteEntry entry = new RouteEntry
                    {
                        Name     = routeAttribute.Name,
                        Route    = route,
                        Template = template,
                    };

                    routeEntries.Add(entry);
                }
            }

            return(routeEntries);
        }
        public void GetCustomAttributesCallsTypeGetCustomAttributes()
        {
            // Arrange
            object[] expected = new object[0];
            Mock<Type> mockType = new Mock<Type>();
            mockType.Setup(t => t.GetCustomAttributes(true)).Returns(expected);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(mockType.Object);

            // Act
            object[] returned = cd.GetCustomAttributes(true);

            // Assert
            Assert.Same(expected, returned);
        }
        public void FindActionThrowsIfControllerContextIsNull() {
            // Arrange
            Type controllerType = typeof(MyController);
            ReflectedAsyncControllerDescriptor cd = new ReflectedAsyncControllerDescriptor(controllerType);

            // Act & assert
            ExceptionHelper.ExpectArgumentNullException(
                delegate {
                    cd.FindAction(null, "someName");
                }, "controllerContext");
        }
        public RenderingFragmentCollection Execute(PageCompositionElement pp)
        {
            RenderingFragmentCollection collection = new RenderingFragmentCollection();

            var allDescendents = pp.GetAllDescendents().OfType <ControllerPageCompositionElement>();

            foreach (var item in allDescendents)
            {
                //todo: cache.
                var descriptor = new ReflectedAsyncControllerDescriptor(item.Controller.GetType());

                using (var writer = new SwitchingHtmlWriter())
                {
                    var fake = new NoResponseHttpContextBase(HttpContext.Current, writer);
                    var rq   = new RequestContext
                    {
                        HttpContext = fake,
                    };
                    rq.RouteData = new RouteData();
                    rq.RouteData.Values.Add("controller", descriptor.ControllerName);
                    rq.RouteData.Values.Add("action", "Index");

                    writer.BeginWriting(item);
                    item.Controller.Execute(rq);
                    writer.EndWriting();


                    collection.RenderingResults.Add(item.ContentId, writer.output[item.ContentId]);

                    //var placeholderOrder = new Dictionary<string, int>();
                    //foreach (var phId in item.PlaceHolders.Keys)
                    //    placeholderOrder.Add(phId,
                    //        output.IndexOf($"[##Placeholder({nonce+"-"+phId})]", StringComparison.OrdinalIgnoreCase));

                    //var phLocations = placeholderOrder.OrderBy(x => x.Value).Select(x => x.Key).ToList();

                    //List<IRenderingFragment> captured = new List<IRenderingFragment>();
                    //var allSegments = phLocations.Select(x => new{Id=x,Marker=$"[##Placeholder({nonce+"-"+x})]"}).ToList();

                    //var remainingOutput = output;
                    //foreach (var segment in allSegments)
                    //{
                    //    var at = remainingOutput.IndexOf(segment.Marker,StringComparison.OrdinalIgnoreCase);
                    //    if (at == -1)
                    //        throw new Exception("Placeholder with id '" + segment.Id+
                    //                            "' was defined in the internal layout, but was not rendered.");

                    //    var capturedHtml = remainingOutput.Substring(0, at);
                    //    if (capturedHtml.Length >0)
                    //        captured.Add(new HtmlOutput(capturedHtml));

                    //    captured.Add(new LayoutSubstitutionOutput{Id=segment.Id});

                    //    remainingOutput = remainingOutput.Substring(at + segment.Marker.Length);
                    //}
                    //if (remainingOutput.Length >0)
                    //    captured.Add(new HtmlOutput(remainingOutput));



                    //collection.WidgetContent.Add(item.ContentId,captured);
                }
            }
            return(collection);
        }