Exemple #1
0
 private bool CalculateRoute(RoutePath path, string httpMethod, RouteBuilder route, RouteNode node)
 {
     using (path.Pin())
     using (var pin = route.Pin())
     {
         if (node.Part.AcceptPath(path, httpMethod))
         {
             route.Add(node.Part);
             
             if (node.Children.Any())
             {
                 foreach (var child in node.Children)
                 {
                     if (CalculateRoute(path, httpMethod, route, child))
                     {
                         pin.Accept();
                         return true;
                     }
                 }                    
             }
             else if (!path.Any())
             {
                 pin.Accept();
                 return true;
             }
         }
         return false;
     }
 }
Exemple #2
0
        public void GenerateRoutesForController(RouteTree routeTree, Type controllerType)
        {
            var    routeAttributes = controllerType.GetCustomAttributes(typeof(RouteAttribute), true);
            var    routeAttribute  = routeAttributes.Length > 0 ? (RouteAttribute)routeAttributes[0] : null;
            string route;

            if (routeAttribute == null)
            {
                route = GenerateDefaultRouteForController(controllerType);
            }
            else
            {
                route = routeAttribute.Value;
            }
            var routePath = new RoutePath(route);

            var currentNode = (IRouteNode)routeTree;
            var leafNodes   = new List <RouteNode>();

            do
            {
                RouteNode nextNode = null;
                if (routePath.Current != null)
                {
                    var routePart = routePath.Consume();
                    var part      = new RouteLiteral(routePart, true);
                    nextNode = new RouteNode(part);
                    AddNode(currentNode, nextNode);

                    if (routePath.Current == null)
                    {
                        part.RouteData[RouteData.ControllerKey] = controllerType;
                        leafNodes.Add(nextNode);
                    }
                }
                // If defined as a default route, then we don't require the last path part
                if (routePath.Current == null)
                {
                    var defaultAttributes = controllerType.GetCustomAttributes(typeof(DefaultAttribute), true);
                    if (defaultAttributes.Length > 0)
                    {
                        var defaultNode = new RouteNode(new RouteDefault(RouteData.ControllerKey, controllerType));
                        AddNode(currentNode, defaultNode);
                        leafNodes.Add(defaultNode);
                    }
                }
                currentNode = nextNode;
            }while (routePath.Current != null);

            foreach (var method in controllerType.GetMethods().Where(x => x.IsPublic && !x.IsStatic && (typeof(ActionResult).IsAssignableFrom(x.ReturnType) || typeof(Task <ActionResult>).IsAssignableFrom(x.ReturnType))))
            {
                GenerateRoutesForAction(routeTree, controllerType, leafNodes, method);
            }
        }
Exemple #3
0
        public void GenerateRoutesForController(RouteTree routeTree, Type controllerType)
        {
            var routeAttributes = controllerType.GetCustomAttributes(typeof(RouteAttribute), true);
            var routeAttribute = routeAttributes.Length > 0 ? (RouteAttribute)routeAttributes[0] : null;
            string route;
            if (routeAttribute == null)
                route = GenerateDefaultRouteForController(controllerType);
            else
                route = routeAttribute.Value;
            var routePath = new RoutePath(route);

            var currentNode = (IRouteNode)routeTree;
            var leafNodes = new List<RouteNode>();

            do
            {
                RouteNode nextNode = null;
                if (routePath.Current != null)
                {
                    var routePart = routePath.Consume();
                    var part = new RouteLiteral(routePart, true);
                    nextNode = new RouteNode(part);
                    AddNode(currentNode, nextNode);                    

                    if (routePath.Current == null)
                    {
                        part.RouteData[RouteData.ControllerKey] = controllerType;
                        leafNodes.Add(nextNode);
                    }
                }
                // If defined as a default route, then we don't require the last path part
                if (routePath.Current == null)
                {
                    var defaultAttributes = controllerType.GetCustomAttributes(typeof(DefaultAttribute), true);
                    if (defaultAttributes.Length > 0)
                    {
                        var defaultNode = new RouteNode(new RouteDefault(RouteData.ControllerKey, controllerType));
                        AddNode(currentNode, defaultNode);
                        leafNodes.Add(defaultNode);
                    }
                }
                currentNode = nextNode;
            } 
            while (routePath.Current != null);

            foreach (var method in controllerType.GetMethods().Where(x => x.IsPublic && !x.IsStatic && (typeof(ActionResult).IsAssignableFrom(x.ReturnType) || typeof(Task<ActionResult>).IsAssignableFrom(x.ReturnType))))
            {
                GenerateRoutesForAction(routeTree, controllerType, leafNodes, method);
            }
        }
Exemple #4
0
        private RouteNode AddNode(IRouteNode parent, RouteNode child)
        {
//            var duplicate = child.FindDuplicate(parent);
//            if (duplicate != null)
//            {
//                child.FindDuplicate(parent);
//                throw new DuplicateRouteException(parent, child, duplicate);
//            }

            if (child.Part is RouteLiteral)
            {
                var routeLiteral = (RouteLiteral)child.Part;
                if (!routeLiteral.IsTerminal)
                {
                    var commonChild = parent.Children.SingleOrDefault(x => x.Part is RouteLiteral && ((RouteLiteral)x.Part).Literal == routeLiteral.Literal && !((RouteLiteral)x.Part).IsTerminal);
                    if (commonChild != null)
                    {
                        return(commonChild);
                    }
                }
            }
            if (child.Part is RouteVariable)
            {
                var routeVariable = (RouteVariable)child.Part;
                if (!routeVariable.IsTerminal)
                {
                    var commonChild = parent.Children.SingleOrDefault(x => x.Part is RouteVariable && !((RouteVariable)x.Part).IsTerminal);
                    if (commonChild != null)
                    {
                        return(commonChild);
                    }
                }
            }

            if (child.Part.RouteData.ContainsKey(Routes.RouteData.RequiredHttpMethodKey) || child.Part is RouteLiteral)
            {
                parent.Children.Insert(0, child);
            }
            else
            {
                parent.Children.Add(child);
            }

            return(child);
        }
Exemple #5
0
        private void GenerateRoutesForAction(RouteTree routeTree, Type controllerType, List <RouteNode> parentNodes, MethodInfo actionMethod)
        {
            var    routeAttributes = actionMethod.GetCustomAttributes(typeof(RouteAttribute), true);
            var    routeAttribute  = routeAttributes.Length > 0 ? (RouteAttribute)routeAttributes[0] : null;
            string route;

            if (routeAttribute == null)
            {
                route = GenerateDefaultRouteForAction(actionMethod);
            }
            else
            {
                route = routeAttribute.Value;
            }

            string httpMethod = null;

            if (actionMethod.IsDefined(typeof(HttpPostAttribute), false))
            {
                httpMethod = "POST";
            }

            bool addToRoot = false;

            if (route.StartsWith("/"))
            {
                addToRoot = true;
            }

            var effectiveNodes = addToRoot ? new[] { (IRouteNode)routeTree } : parentNodes.ToArray();

            foreach (var node in effectiveNodes)
            {
                var routePath   = new RoutePath(route);
                var currentNode = node;
                do
                {
                    RouteNode nextNode = null;

                    if (routePath.Current != null)
                    {
                        var part = routePath.Consume();
                        if (part == "@")
                        {
                            part = GenerateDefaultRouteForAction(actionMethod);
                        }
                        RoutePart routePart;
                        if (part == "*")
                        {
                            var parameter = actionMethod.GetParameters().Single();
                            routePart = new RouteWildcard(parameter);
                        }
                        else if (part.StartsWith("{") && part.EndsWith("}"))
                        {
                            var id        = part.ChopStart("{").ChopEnd("}");
                            var parameter = actionMethod.GetParameters().Single(x => x.Name == id);
                            routePart = new RouteVariable(routePath.Current == null, parameter);
                        }
                        else
                        {
                            routePart = new RouteLiteral(part, routePath.Current == null);
                        }

                        nextNode = new RouteNode(routePart);

                        if (routePath.Current == null)
                        {
                            routePart.RouteData[RouteData.ActionKey]     = actionMethod;
                            routePart.RouteData[RouteData.ControllerKey] = controllerType;
                            if (httpMethod != null)
                            {
                                routePart.RouteData[RouteData.RequiredHttpMethodKey] = httpMethod;
                            }
                        }

                        nextNode = AddNode(currentNode, nextNode);
                    }
                    if (routePath.Current == null)
                    {
                        if (actionMethod.IsDefined(typeof(DefaultAttribute), false))
                        {
                            AddNode(currentNode, new RouteNode(new RouteDefault(RouteData.ActionKey, actionMethod)));
                        }
                    }

                    currentNode = nextNode;
                }while (routePath.Current != null);
            }
        }
Exemple #6
0
        private bool CalculateRoute(RoutePath path, string httpMethod, RouteBuilder route, RouteNode node)
        {
            using (path.Pin())
                using (var pin = route.Pin())
                {
                    if (node.Part.AcceptPath(path, httpMethod))
                    {
                        route.Add(node.Part);

                        if (node.Children.Any())
                        {
                            foreach (var child in node.Children)
                            {
                                if (CalculateRoute(path, httpMethod, route, child))
                                {
                                    pin.Accept();
                                    return(true);
                                }
                            }
                        }
                        else if (!path.Any())
                        {
                            pin.Accept();
                            return(true);
                        }
                    }
                    return(false);
                }
        }
Exemple #7
0
        private void GenerateRoutesForAction(RouteTree routeTree, Type controllerType, List<RouteNode> parentNodes, MethodInfo actionMethod)
        {
            var routeAttributes = actionMethod.GetCustomAttributes(typeof(RouteAttribute), true);
            var routeAttribute = routeAttributes.Length > 0 ? (RouteAttribute)routeAttributes[0] : null;
            string route;
            if (routeAttribute == null)
                route = GenerateDefaultRouteForAction(actionMethod);
            else
                route = routeAttribute.Value;

            string httpMethod = null;
            if (actionMethod.IsDefined(typeof(HttpPostAttribute), false))
            {
                httpMethod = "POST";
            }

            bool addToRoot = false;
            if (route.StartsWith("/"))
            {
                addToRoot = true;
            }

            var effectiveNodes = addToRoot ? new[] { (IRouteNode)routeTree } : parentNodes.ToArray();

            foreach (var node in effectiveNodes)
            {
                var routePath = new RoutePath(route);
                var currentNode = node;
                do
                {
                    RouteNode nextNode = null;

                    if (routePath.Current != null)
                    {
                        var part = routePath.Consume();
                        if (part == "@")
                        {
                            part = GenerateDefaultRouteForAction(actionMethod);
                        }
                        RoutePart routePart;
                        if (part == "*")
                        {
                            var parameter = actionMethod.GetParameters().Single();
                            routePart = new RouteWildcard(parameter);
                        }                        
                        else if (part.StartsWith("{") && part.EndsWith("}"))
                        {
                            var pieces = part.ChopStart("{").ChopEnd("}").Split(':');
                            var id = pieces[0];
                            var parameter = actionMethod.GetParameters().Single(x => x.Name == id);
                            var variable = new RouteVariable(routePath.Current == null, parameter);

                            var constraints = pieces.Skip(1).ToArray();
                            foreach (var name in constraints)
                            {
                                var constraint = RouteConstraints.GetConstraint(name);
                                variable.Constraints.Add(constraint);
                            }

                            routePart = variable;
                        }
                        else
                        {
                            routePart = new RouteLiteral(part, routePath.Current == null);
                        }

                        nextNode = new RouteNode(routePart);

                        if (routePath.Current == null)
                        {
                            routePart.RouteData[RouteData.ActionKey] = actionMethod;
                            routePart.RouteData[RouteData.ControllerKey] = controllerType;
                            if (httpMethod != null)
                                routePart.RouteData[RouteData.RequiredHttpMethodKey] = httpMethod;
                        }                            
                        
                        nextNode = AddNode(currentNode, nextNode);                        
                    }
                    if (routePath.Current == null)
                    {
                        if (actionMethod.IsDefined(typeof(DefaultAttribute), false))
                            AddNode(currentNode, new RouteNode(new RouteDefault(RouteData.ActionKey, actionMethod)));
                    }

                    currentNode = nextNode;
                }
                while (routePath.Current != null);
            }
        }
Exemple #8
0
        private RouteNode AddNode(IRouteNode parent, RouteNode child)
        {
//            var duplicate = child.FindDuplicate(parent);
//            if (duplicate != null)
//            {
//                child.FindDuplicate(parent);
//                throw new DuplicateRouteException(parent, child, duplicate);
//            }
                
            if (child.Part is RouteLiteral)
            {
                var routeLiteral = (RouteLiteral)child.Part;
                if (!routeLiteral.IsTerminal)
                {
                    var commonChild = parent.Children.SingleOrDefault(x => x.Part is RouteLiteral && ((RouteLiteral)x.Part).Literal == routeLiteral.Literal && !((RouteLiteral)x.Part).IsTerminal);
                    if (commonChild != null)
                    {
                        return commonChild;
                    }
                }
            }
            if (child.Part is RouteVariable)
            {
                var routeVariable = (RouteVariable)child.Part;
                if (!routeVariable.IsTerminal)
                {
                    var commonChild = parent.Children.SingleOrDefault(x => x.Part is RouteVariable && !((RouteVariable)x.Part).IsTerminal);
                    if (commonChild != null)
                    {
                        return commonChild;
                    }
                }
            }
            
            if (child.Part.RouteData.ContainsKey(Routes.RouteData.RequiredHttpMethodKey) || child.Part is RouteLiteral)
                parent.Children.Insert(0, child);
            else
                parent.Children.Add(child);
                
            return child;
        }