コード例 #1
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);
        }
コード例 #2
0
ファイル: RouteBuilder.cs プロジェクト: randommuses/jasper
        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();


            Type inputType     = DetermineInputType(method);
            var  hasPrimitives = method.GetParameters().Any(x => x.ParameterType == typeof(Guid) || RouteArgument.Conversions.Has(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, env => Task.CompletedTask)
            {
                HandlerType = handlerType,
                Method      = method,
                InputType   = inputType
            };

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

            return(route);
        }
コード例 #3
0
ファイル: RouteArgument.cs プロジェクト: randommuses/jasper
 protected bool Equals(RouteArgument other)
 {
     return(string.Equals(Key, other.Key) && Position == other.Position);
 }