예제 #1
0
 /// <summary>
 /// Constructs a new route by appending a path to this instance
 /// </summary>
 /// <param name="path">The path to append.</param>
 /// <param name="caseinsensitive">If set to <c>true</c>, comapres are performed case insensitive.</param>
 /// <param name="target">The target method.</param>
 /// <returns>The combined route</returns>
 public RouteParser Append(string path, bool caseinsensitive, RouteEntry target)
 {
     return(Append(new RouteParser(path, caseinsensitive, target)));
 }
예제 #2
0
        private static RouteParser BuildParse(IEnumerable <Controller> controllers, ControllerRouterConfig config)
        {
            var controller_routes =
                controllers.SelectMany(x =>
            {
                string name;
                var nameattr = x.GetType().GetCustomAttributes(typeof(NameAttribute), false).Cast <NameAttribute>().FirstOrDefault();
                // Extract controller name
                if (nameattr != null)
                {
                    name = nameattr.Name;
                }
                else
                {
                    name = x.GetType().Name;
                    if (config.ControllerSuffixRemovals != null)
                    {
                        foreach (var rm in config.ControllerSuffixRemovals)
                        {
                            while (!string.IsNullOrWhiteSpace(rm) && name.EndsWith(rm, StringComparison.InvariantCultureIgnoreCase))
                            {
                                name = name.Substring(0, name.Length - rm.Length);
                            }
                        }
                    }

                    if (config.LowerCaseNames)
                    {
                        name = name.ToLowerInvariant();
                    }
                }

                var routes = x.GetType().GetCustomAttributes(typeof(RouteAttribute), false).Cast <RouteAttribute>().Select(y => y.Route);

                // Add default route, if there are no route attributes
                if (routes.Count() == 0)
                {
                    routes = new[] { string.Empty }
                }
                ;

                return(routes.Distinct().Select(y => new
                {
                    Controller = x,
                    ControllerRoute = y
                }));
            }
                                       ).ToArray();

            var interface_expanded_routes =
                controller_routes.SelectMany(x =>
            {
                var interfaces     = x.Controller.GetType().GetParentInterfaces <IControllerPrefix>();
                var interfacenames = interfaces
                                     .Select(y => x.Controller.GetType().GetParentInterfaceSequence(y).Reverse().Where(z => z != x.Controller.GetType() && z != typeof(IControllerPrefix)))
                                     .Select(y => string.Join("/", y.Select(z => z.GetItemName(config))));

                if (interfacenames.Count() == 0)
                {
                    interfacenames = new[] { string.Empty }
                }
                ;

                return(interfacenames.Distinct().Select(y => new
                {
                    Controller = x.Controller,
                    ControllerRoute = x.ControllerRoute,
                    InterfacePath = (y ?? string.Empty)
                }));
            }
                                             ).ToArray();


            var target_method_routes =
                interface_expanded_routes.SelectMany(x =>
            {
                return
                (x.Controller.GetType()
                 .GetMethods(BindingFlags.Public | BindingFlags.Instance)
                 .Where(y => y.ReturnType == typeof(void) || typeof(IResult).IsAssignableFrom(y.ReturnType) || typeof(Task).IsAssignableFrom(y.ReturnType))
                 .Select(y => new
                {
                    Controller = x.Controller,
                    ControllerRoute = x.ControllerRoute,
                    InterfacePath = x.InterfacePath,
                    Method = y
                }));
            }
                                                     ).ToArray();

            var target_routes =
                target_method_routes.SelectMany(x =>
            {
                var routes = x.Method.GetCustomAttributes(typeof(RouteAttribute), false).Cast <RouteAttribute>().Select(y => y.Route);

                // Add default route, if there are no route attributes
                if (routes.Count() == 0)
                {
                    routes = new[] { string.Empty }
                }
                ;

                return(routes.Select(y => new
                {
                    Controller = x.Controller,
                    ControllerRoute = x.ControllerRoute,
                    InterfacePath = x.InterfacePath,
                    Method = x.Method,
                    MethodRoute = y
                }));
            }
                                                ).ToArray();

            // Now we have the cartesian product of all route/controller/action pairs, then build the target strings
            var tmp = new RouteParser(config.Template, !config.CaseSensitive, null);
            var defaultcontrollername = tmp.GetDefaultValue(config.ControllerGroupName);
            var defaultactionname     = tmp.GetDefaultValue(config.ActionGroupName);

            var target_strings =
                target_routes.SelectMany(x =>
            {
                var methodverbs = x.Method.GetCustomAttributes(typeof(HttpVerbFilterAttribute), false).Cast <HttpVerbFilterAttribute>().Select(b => b.Verb.ToUpperInvariant());
                var entry       = new RouteEntry(x.Controller, x.Method, methodverbs.ToArray(), null);

                var path = new RouteParser("/", !config.CaseSensitive, entry);

                if (!string.IsNullOrWhiteSpace(x.InterfacePath))
                {
                    if (x.InterfacePath.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(x.InterfacePath, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        path = path.Append(x.InterfacePath, !config.CaseSensitive, entry);
                    }
                }

                var ct = string.IsNullOrWhiteSpace(x.ControllerRoute) ? config.Template : x.ControllerRoute;

                if (!string.IsNullOrWhiteSpace(ct))
                {
                    if (ct.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(ct, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        if (!path.Path.EndsWith("/", StringComparison.Ordinal))
                        {
                            ct = "/" + ct;
                        }
                        path = path.Append(ct, !config.CaseSensitive, entry);
                    }
                }

                var mt = x.MethodRoute;
                if (!string.IsNullOrWhiteSpace(mt))
                {
                    if (mt.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(mt, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        path = path.Bind(config.ActionGroupName, string.Empty, !config.CaseSensitive, true);
                        if (!path.Path.EndsWith("/", StringComparison.Ordinal))
                        {
                            mt = "/" + mt;
                        }

                        path = path.Append(mt, !config.CaseSensitive, entry);
                    }
                }

                var controllername = x.Controller.GetType().GetItemName(config);
                var actionname     = x.Method.GetItemName(config);

                var controllernames = new List <string>();
                var actionnames     = new List <string>();

                if (!config.HideDefaultController || controllername != defaultcontrollername)
                {
                    controllernames.Add(controllername);
                }
                if (!config.HideDefaultAction || actionname != defaultactionname)
                {
                    actionnames.Add(actionname);
                }
                if (!string.IsNullOrEmpty(defaultcontrollername) && controllername == defaultcontrollername)
                {
                    controllernames.Add(string.Empty);
                }
                if (!string.IsNullOrEmpty(defaultactionname) && actionname == defaultactionname)
                {
                    actionnames.Add(string.Empty);
                }

                // Cartesian product with controller and action names bound
                return(controllernames
                       .SelectMany(y => actionnames.Select(
                                       z => path
                                       .Bind(config.ControllerGroupName, y, !config.CaseSensitive, true)
                                       .Bind(config.ActionGroupName, z, !config.CaseSensitive, true)
                                       .PrunePath()
                                       .ReplaceTarget(x.Controller, x.Method, methodverbs.ToArray())
                                       )
                                   ));
            }
                                         )
                .Distinct(x => x.ToString())
                .ToArray();

            var merged = RouteParser.Merge(target_strings);

            if (config.Debug)
            {
                Console.WriteLine("All target paths:");
                foreach (var x in target_strings)
                {
                    Console.WriteLine(x);
                }

                Console.WriteLine("Map structure:");
                Console.WriteLine(merged.ToString());
            }

            return(merged);
        }
예제 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:Ceen.Mvc.RouteParser2.Result"/> struct.
 /// </summary>
 /// <param name="entry">The entry to represent.</param>
 public Result(RouteEntry entry)
 {
     Route = entry;
 }
예제 #4
0
        private static RouteParser BuildParse(IEnumerable <Controller> controllers, ControllerRouterConfig config)
        {
            var target_routes =
                ParseControllers(controllers, config)

                // Attach custom controller routes
                .Concat(
                    controllers.OfType <ManualRoutingController>().SelectMany(x => x.Routes)
                    )
                .ToArray();

            // Now we have the cartesian product of all route/controller/action pairs, then build the target strings
            var tmp = new RouteParser(config.Template, !config.CaseSensitive, null);
            var defaultcontrollername = tmp.GetDefaultValue(config.ControllerGroupName);
            var defaultactionname     = tmp.GetDefaultValue(config.ActionGroupName);

            var target_strings =
                target_routes.SelectMany(x =>
            {
                // Provide a hook point for the dynamic routing option
                if (x.Controller is IIDynamicConfiguredController idc)
                {
                    x = idc.PatchRoute(x);
                }

                var entry = new RouteEntry(x.Controller, x.Method, x.Verbs, null);

                var path = new RouteParser("/", !config.CaseSensitive, entry);

                if (!string.IsNullOrWhiteSpace(x.InterfacePath))
                {
                    if (x.InterfacePath.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(x.InterfacePath, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        path = path.Append(x.InterfacePath, !config.CaseSensitive, entry);
                    }
                }

                var ct = string.IsNullOrWhiteSpace(x.ControllerPath) ? config.Template : x.ControllerPath;

                if (!string.IsNullOrWhiteSpace(ct))
                {
                    if (ct.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(ct, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        if (!path.Path.EndsWith("/", StringComparison.Ordinal))
                        {
                            ct = "/" + ct;
                        }
                        path = path.Append(ct, !config.CaseSensitive, entry);
                    }
                }

                var mt = x.MethodPath;
                if (!string.IsNullOrWhiteSpace(mt))
                {
                    if (mt.StartsWith("/", StringComparison.Ordinal))
                    {
                        path = new RouteParser(mt, !config.CaseSensitive, entry);
                    }
                    else
                    {
                        path = path.Bind(config.ActionGroupName, string.Empty, !config.CaseSensitive, true);
                        if (!path.Path.EndsWith("/", StringComparison.Ordinal))
                        {
                            mt = "/" + mt;
                        }

                        path = path.Append(mt, !config.CaseSensitive, entry);
                    }
                }

                var controllername = x.Controller.GetType().GetItemName(config);
                var actionname     = x.Method.GetItemName(config);

                var controllernames = new List <string>();
                var actionnames     = new List <string>();

                if (!config.HideDefaultController || controllername != defaultcontrollername)
                {
                    controllernames.Add(controllername);
                }
                if (!config.HideDefaultAction || actionname != defaultactionname)
                {
                    actionnames.Add(actionname);
                }
                if (!string.IsNullOrEmpty(defaultcontrollername) && controllername == defaultcontrollername)
                {
                    controllernames.Add(string.Empty);
                }
                if (!string.IsNullOrEmpty(defaultactionname) && actionname == defaultactionname)
                {
                    actionnames.Add(string.Empty);
                }

                // Cartesian product with controller and action names bound
                return(controllernames
                       .SelectMany(y => actionnames.Select(
                                       z => path
                                       .Bind(config.ControllerGroupName, y, !config.CaseSensitive, true)
                                       .Bind(config.ActionGroupName, z, !config.CaseSensitive, true)
                                       .PrunePath()
                                       .ReplaceTarget(x.Controller, x.Method, x.Verbs)
                                       )
                                   ));
            }
                                         )
                .Distinct(x => x.ToString())
                .ToArray();

            var merged = RouteParser.Merge(target_strings);

            if (config.Debug)
            {
                Console.WriteLine("All target paths:");
                foreach (var x in target_strings)
                {
                    Console.WriteLine(x);
                }

                Console.WriteLine("Map structure:");
                Console.WriteLine(merged.ToString());
            }

            return(merged);
        }