/// <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) { leaf.Route = new Route { ActionType = method, ControllerType = controllerType, Method = info.Method, Path = path.ToArray(), Parameters = BuildParameters(method), IsAsyncMethod = (AsyncStateMachineAttribute)method.GetCustomAttribute(typeof(AsyncStateMachineAttribute)) != null }; } } ApplyControllerAttributes(leaf.Route, controllerType); ApplyActionAttributes(leaf.Route, method); } } } return(routes); }
/// <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); }
/// <summary> /// Creates new leaf in specified path /// </summary> public RouteLeaf(RoutePath path, RouteLeaf parent) { Children = new List <RouteLeaf>(); Path = path; Parent = parent; if (parent != null && !string.IsNullOrEmpty(parent.Path.Value)) { Index = parent.Index + 1; } }
/// <summary> /// Return true, if leaf equals to specified path /// </summary> public bool PathEquals(RoutePath path) { return(path.Type == Path.Type && path.Value.Equals(Path.Value, StringComparison.InvariantCultureIgnoreCase)); }