Exemplo n.º 1
0
        /// <summary>
        /// Finds matched route from the list with specified request
        /// </summary>
        public RouteMatch Find(IEnumerable <RouteLeaf> routes, HttpRequest request)
        {
            //split path to route parts
            string[] parts = request.Path.Split('/', StringSplitOptions.RemoveEmptyEntries);
            if (parts.Length == 0)
            {
                parts = new[] { "" }
            }
            ;

            RouteLeaf route = null;

            foreach (RouteLeaf leaf in routes)
            {
                RouteLeaf found = FindRouteInLeaf(leaf, request.Method, parts, 0);
                if (found != null)
                {
                    route = found;
                    break;
                }
            }

            if (route == null)
            {
                return(null);
            }

            RouteMatch match = new RouteMatch();

            match.Values = new Dictionary <string, object>(StringComparer.InvariantCultureIgnoreCase);

            match.Route = route.Route;

            do
            {
                RoutePath path = route.Path;

                //if type is optional parameter we dont need to check if equals
                //we just need to read the part value and put it into value list (if doesn't exists put default value)
                if (path.Type == RouteType.OptionalParameter)
                {
                    match.Values.Add(path.Value,
                                     parts.Length <= route.Index
                                         ? null
                                         : parts[route.Index]);
                }

                //if type is parameter we dont need to check if equals
                //we just need to read the part value and put it into value list
                else if (path.Type == RouteType.Parameter)
                {
                    match.Values.Add(path.Value, parts[route.Index]);
                }

                route = route.Parent;
            }while (route != null);

            return(match);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates RoutePath table from the controller type, action method reflection info and full path.
        /// </summary>
        private List <RoutePath> GetRoutePath(MethodInfo action, string fullpath)
        {
            List <RoutePath> result = new List <RoutePath>();

            if (string.IsNullOrEmpty(fullpath))
            {
                result.Add(new RoutePath
                {
                    Type  = RouteType.Text,
                    Value = ""
                });

                return(result);
            }

            //split path to parts.
            //each part will be replaced to RoutePath class with extra information
            string[] parts = fullpath.ToLower(new CultureInfo("en-US")).Split('/', StringSplitOptions.RemoveEmptyEntries);

            foreach (string part in parts)
            {
                if (string.IsNullOrEmpty(part))
                {
                    continue;
                }

                RoutePath route = new RoutePath();

                if (part == "[action]")
                {
                    route.Type  = RouteType.Text;
                    route.Value = action.Name.ToLower(new CultureInfo("en-US"));
                }

                //if the part is parameter check if it's optional or not and set value as parameter name
                else if (part.StartsWith('{'))
                {
                    route.Type = part.Substring(1, 1) == "?"
                                     ? RouteType.OptionalParameter
                                     : RouteType.Parameter;

                    route.Value = route.Type == RouteType.OptionalParameter
                                      ? part.Substring(2, part.Length - 3)
                                      : part.Substring(1, part.Length - 2);
                }

                //for all other kinds set the value directly as text type.
                else
                {
                    route.Type  = RouteType.Text;
                    route.Value = part;
                }

                result.Add(route);
            }

            return(result);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Creates all Route objects of the specified Controller type
        /// </summary>
        public IEnumerable <RouteLeaf> BuildRoutes(Type controllerType)
        {
            //find base path for the controller
            List <RouteLeaf> routes = CreateControllerRoutes(controllerType);
            List <RouteLeaf> edges  = new List <RouteLeaf>();

            foreach (RouteLeaf leaf in routes)
            {
                edges.AddRange(GetEdgeLeaves(leaf));
            }

            MethodInfo[] methods = controllerType.GetMethods();
            foreach (MethodInfo method in methods)
            {
                //find method route if exists
                List <RouteInfo> methodRoutes = FindActionRoute(method);
                if (methodRoutes.Count == 0)
                {
                    continue;
                }

                foreach (RouteLeaf cleaf in edges)
                {
                    foreach (RouteInfo info in methodRoutes)
                    {
                        //get route table from the fullpath
                        List <RoutePath> path = GetRoutePath(method, info.Pattern);

                        RouteLeaf leaf = cleaf;
                        for (int i = 0; i < path.Count; i++)
                        {
                            RoutePath rp    = path[i];
                            RouteLeaf child = new RouteLeaf(rp, leaf);
                            leaf.Children.Add(child);
                            leaf = child;

                            if (i == path.Count - 1)
                            {
                                bool isAsync = (AsyncStateMachineAttribute)method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null;
                                if (!isAsync && method.ReturnType.IsGenericType)
                                {
                                    if (typeof(Task).IsAssignableFrom(method.ReturnType.GetGenericTypeDefinition()))
                                    {
                                        isAsync = true;
                                    }
                                }

                                leaf.Route = new Route
                                {
                                    ActionType     = method,
                                    ControllerType = controllerType,
                                    Method         = info.Method,
                                    Path           = path.ToArray(),
                                    Parameters     = BuildParameters(method),
                                    IsAsyncMethod  = isAsync
                                };
                            }
                        }

                        ApplyControllerAttributes(leaf.Route, controllerType);
                        ApplyActionAttributes(leaf.Route, method);
                    }
                }
            }

            return(routes);
        }