示例#1
0
        public static JasperRoute Build(Type handlerType, MethodInfo method)
        {
            var route = Rules.FirstValue(x => x.DetermineRoute(handlerType, method));

            if (route == null)
            {
                throw new InvalidOperationException(
                          $"Jasper does not know how to make an Http route from the method {handlerType.NameInCode()}.{method.Name}()");
            }

            route.InputType   = DetermineInputType(method);
            route.HandlerType = handlerType;
            route.Method      = method;

            var hasPrimitives = method.GetParameters().Any(x =>
                                                           x.ParameterType == typeof(string) || RouteArgument.CanParse(x.ParameterType));

            if (hasPrimitives)
            {
                for (var i = 0; i < route.Segments.Count; i++)
                {
                    var current       = route.Segments[i].SegmentPath;
                    var isParameter   = current.StartsWith("{") && current.EndsWith("}");
                    var parameterName = current.TrimStart('{').TrimEnd('}');


                    var parameter = method.GetParameters().FirstOrDefault(x => x.Name == parameterName);
                    if (parameter != null)
                    {
                        var argument = new RouteArgument(parameter, i);
                        route.Segments[i] = argument;
                    }

                    if (isParameter && parameter == null)
                    {
                        throw new InvalidOperationException(
                                  $"Required parameter '{current}' could not be resoved in method {handlerType.FullNameInCode()}.{method.Name}()");
                    }
                }
            }

            var spreads = method.GetParameters().Where(x => x.IsSpread()).ToArray();

            if (spreads.Length > 1)
            {
                throw new InvalidOperationException(
                          $"An HTTP action method can only take in either '{JasperRoute.PathSegments}' or '{JasperRoute.RelativePath}', but not both. Error with action {handlerType.FullName}.{method.Name}()");
            }

            if (spreads.Length == 1)
            {
                var spread = new Spread(route.Segments.Count, spreads.Single());
                route.Segments.Add(spread);
            }

            method.ForAttribute <RouteNameAttribute>(att => route.Name = att.Name);

            return(route);
        }
示例#2
0
        public static Route Build(string pattern, Type handlerType, MethodInfo method)
        {
            pattern = pattern.Replace("___", "-").Replace("__", "_@");

            var parts = pattern.Split('_')
                        .Select(x => x.Replace("@", "_")).ToArray();


            var verb = HttpVerbs.All.FirstOrDefault(x => x.EqualsIgnoreCase(parts[0]));

            if (verb.IsNotEmpty())
            {
                parts = parts.Skip(1).ToArray();
            }
            else
            {
                verb = HttpVerbs.GET;
            }

            var segments = parts
                           .Select((x, position) => new Segment(x.ToLowerInvariant(), position))
                           .OfType <ISegment>()
                           .ToArray();

            if (SpecialClassNames.Contains(handlerType.Name) && SpecialMethodNames.ContainsKey(method.Name))
            {
                pattern  = "/";
                verb     = SpecialMethodNames[method.Name];
                segments = new ISegment[0];
            }


            Type inputType = DetermineInputType(method);

            var hasPrimitives = method.GetParameters().Any(x => x.ParameterType == typeof(string) || RoutingFrames.CanParse(x.ParameterType));

            if (hasPrimitives)
            {
                for (var i = 0; i < segments.Length; i++)
                {
                    var current   = parts[i];
                    var parameter = method.GetParameters().FirstOrDefault(x => x.Name == current);
                    if (parameter != null)
                    {
                        var argument = new RouteArgument(parameter, i);
                        segments[i] = argument;
                    }
                }
            }
            else if (inputType != null)
            {
                var members = inputType.GetProperties().OfType <MemberInfo>().Concat(inputType.GetFields()).ToArray();

                for (var i = 0; i < segments.Length; i++)
                {
                    var current = parts[i];
                    var member  = members.FirstOrDefault(x => x.Name == current);
                    if (member != null)
                    {
                        var argument = new RouteArgument(member, i);
                        segments[i] = argument;
                    }
                }
            }

            var spreads = method.GetParameters().Where(x => x.IsSpread()).ToArray();

            if (spreads.Length > 1)
            {
                throw new InvalidOperationException($"An HTTP action method can only take in either '{Route.PathSegments}' or '{Route.RelativePath}', but not both. Error with action {handlerType.FullName}.{method.Name}()");
            }

            if (spreads.Length == 1)
            {
                segments = segments.Concat(new ISegment[] { new Spread(segments.Length) }).ToArray();
            }

            var route = new Route(segments, verb)
            {
                HandlerType = handlerType,
                Method      = method,
                InputType   = inputType
            };

            method.ForAttribute <RouteNameAttribute>(att => route.Name = att.Name);

            return(route);
        }
示例#3
0
        public static Route Build(string pattern, Type handlerType, MethodInfo method)
        {
            pattern = pattern.Replace("___", "-").Replace("__", "_@");

            var parts = pattern.Split('_')
                        .Select(x => x.Replace("@", "_")).ToArray();


            var verb = HttpVerbs.All.FirstOrDefault(x => x.EqualsIgnoreCase(parts[0]));

            if (verb.IsNotEmpty())
            {
                parts = parts.Skip(1).ToArray();
            }
            else
            {
                verb = HttpVerbs.GET;
            }

            var segments = parts
                           .Select((x, position) => new Segment(x.ToLowerInvariant(), position))
                           .OfType <ISegment>()
                           .ToArray();

            if (SpecialClassNames.Contains(handlerType.Name) && SpecialMethodNames.ContainsKey(method.Name))
            {
                pattern  = "/";
                verb     = SpecialMethodNames[method.Name];
                segments = new ISegment[0];
            }


            // TODO -- eliminate the old Fubu input model routing?
            Type inputType = DetermineInputType(method);

            var hasPrimitives = method.GetParameters().Any(x => x.ParameterType == typeof(string) || RoutingFrames.CanParse(x.ParameterType));

            if (hasPrimitives)
            {
                for (var i = 0; i < segments.Length; i++)
                {
                    var current   = parts[i];
                    var parameter = method.GetParameters().FirstOrDefault(x => x.Name == current);
                    if (parameter != null)
                    {
                        var argument = new RouteArgument(parameter, i);
                        segments[i] = argument;
                    }
                }
            }
            else if (inputType != null)
            {
                var members = inputType.GetProperties().OfType <MemberInfo>().Concat(inputType.GetFields()).ToArray();

                for (var i = 0; i < segments.Length; i++)
                {
                    var current = parts[i];
                    var member  = members.FirstOrDefault(x => x.Name == current);
                    if (member != null)
                    {
                        var argument = new RouteArgument(member, i);
                        segments[i] = argument;
                    }
                }
            }

            var route = new Route(segments, verb)
            {
                HandlerType = handlerType,
                Method      = method,
                InputType   = inputType
            };

            method.ForAttribute <RouteNameAttribute>(att => route.Name = att.Name);

            return(route);
        }
示例#4
0
        public static Route Build(RoutePattern pattern, Type handlerType, MethodInfo method)
        {
            var inputType = DetermineInputType(method);

            var hasPrimitives = method.GetParameters().Any(x =>
                                                           x.ParameterType == typeof(string) || RoutingFrames.CanParse(x.ParameterType));

            if (hasPrimitives)
            {
                for (var i = 0; i < pattern.Segments.Length; i++)
                {
                    var current       = pattern.Segments[i].SegmentPath;
                    var isParameter   = current.StartsWith("{") && current.EndsWith("}");
                    var parameterName = current.TrimStart('{').TrimEnd('}');


                    var parameter = method.GetParameters().FirstOrDefault(x => x.Name == parameterName);
                    if (parameter != null)
                    {
                        var argument = new RouteArgument(parameter, i);
                        pattern.Segments[i] = argument;
                    }

                    if (isParameter && parameter == null)
                    {
                        throw new InvalidOperationException($"Required parameter '{current}' could not be resoved in method {handlerType.FullNameInCode()}.{method.Name}()");
                    }
                }
            }
            else if (inputType != null)
            {
                var members = inputType.GetProperties().OfType <MemberInfo>().Concat(inputType.GetFields()).ToArray();

                for (var i = 0; i < pattern.Segments.Length; i++)
                {
                    var current = pattern.Segments[i].SegmentPath;
                    var member  = members.FirstOrDefault(x => x.Name == current);
                    if (member != null)
                    {
                        var argument = new RouteArgument(member, i);
                        pattern.Segments[i] = argument;
                    }
                }
            }

            var spreads = method.GetParameters().Where(x => x.IsSpread()).ToArray();

            if (spreads.Length > 1)
            {
                throw new InvalidOperationException(
                          $"An HTTP action method can only take in either '{Route.PathSegments}' or '{Route.RelativePath}', but not both. Error with action {handlerType.FullName}.{method.Name}()");
            }

            var segments = pattern.Segments;

            if (spreads.Length == 1)
            {
                segments = segments.Concat(new ISegment[] { new Spread(segments.Length) }).ToArray();
            }

            var route = new Route(segments, pattern.Method)
            {
                HandlerType = handlerType,
                Method      = method,
                InputType   = inputType
            };

            method.ForAttribute <RouteNameAttribute>(att => route.Name = att.Name);

            return(route);
        }