예제 #1
0
            public RouteMethodRecord(RouteAttribute routeProperties, string prefix, MethodInfo routeMethod)
            {
                string routePath = routeProperties.RoutePath.Trim().TrimEnd('/');
                var    matches   = regexRoutePathParser.Matches(routePath);
                {
                    this.RouteProperties = routeProperties;
                    this.RouteMethod     = routeMethod;
                }
                {
                    List <string> regexFragments = new List <string>();
                    int           index          = 0;
                    foreach (Match match in matches)
                    {
                        regexFragments.Add(Regex.Escape(routePath.Substring(index, match.Index - index)));
                        regexFragments.Add(string.Format(@"(?<{0}>[^/]*?)", match.Groups["name"].Value));
                        index = match.Index + match.Length;
                    }
                    regexFragments.Add(Regex.Escape(routePath.Substring(index, routePath.Length - index)));

                    string regex = regexFragments.Aggregate((a, b) => a + b);
                    this.RoutePathRegex = new Regex(string.Format("^{0}{1}$", Regex.Escape(prefix), regex));
                }
                {
                    this.Parameters = matches
                                      .Cast <Match>()
                                      .Select(m => m.Groups["name"].Value)
                                      .ToArray();
                }
                {
                    var parameterInfoNames = this.RouteMethod
                                             .GetParameters()
                                             .Select(p => p.Name)
                                             .ToArray();

                    var parameterIndices = Enumerable
                                           .Range(0, parameterInfoNames.Length)
                                           .ToDictionary(i => parameterInfoNames[i], i => i);

                    this.ParameterIndexMapping = this.Parameters
                                                 .Select(p => parameterIndices[p])
                                                 .ToArray();
                }
            }
예제 #2
0
        public static void BuildRouter(string baseRoute, MethodInfo method, ref RouteInfo routeInfo, RouteAttribute attribute = null)
        {
            routeInfo = new RouteInfo();
            string restPart = attribute != null && !string.IsNullOrWhiteSpace(attribute.Route)
                ? attribute.Route
                : method.Name;

            string absoluteUrl = Regex.Replace($"/{baseRoute}/{restPart}", "(/)+", "/");

            string[] segmentUrl = absoluteUrl.Split('/', StringSplitOptions.RemoveEmptyEntries);

            MatchCollection matches = Regex.Matches(absoluteUrl,
                                                    @"(?<={)(?<name>[a-zA-Z0-9_-]+)(?=})",
                                                    RegexOptions.IgnoreCase | RegexOptions.Multiline);

            if (matches.Count > 0)
            {
                absoluteUrl = $"{Regex.Replace(absoluteUrl, @"{(?<name>[a-zA-Z0-9_-]+)}", @"([a-zA-Z0-9_-]+)")}";
                //var data = Regex.Matches("/api/param1/param2", absoluteUrl);

                var param = method.GetParameters()
                            .Select(x => x.Name)
                            .ToArray();
                routeInfo.ParamSegments = segmentUrl.Select(x => Array.FindIndex(param, p => $"{{{p}}}" == x)).ToArray();
            }

            routeInfo.AbsoluteUrl = $"^{absoluteUrl}$";
            routeInfo.Action      = method.DeclaringType;
            routeInfo.Method      = method;

            ParameterInfo[] parameters = method.GetParameters();

            routeInfo.ParamNames     = parameters.Select(x => x.Name.ToLower()).ToArray();
            routeInfo.BodyParametter = parameters.FirstOrDefault(x => x.ParameterType != typeof(string))?.ParameterType.FullName;

            routeInfo.HttpVers = attribute != null
                ? attribute.HttpVerb
                : HttpMethod.GET;
        }
예제 #3
0
        private static bool ExecuteAbsoluteMethod(List <Type> types, HttpListenerRequest request, HttpListenerResponse response)
        {
            string[] segmentQuery = request.Url.Query.TrimStart('?')
                                    .Split('&', StringSplitOptions.RemoveEmptyEntries);

            string url = request.Url.AbsolutePath.TrimEnd('/');

            MethodInfo[] methods = types.SelectMany(x => x.GetMethods()
                                                    .Where(y => y.DeclaringType.Name == x.Name))
                                   .ToArray();
            RouteAttribute[] absoluteRoutes = methods
                                              .SelectMany(x => x.GetCustomAttributes <RouteAttribute>())
                                              .ToList()
                                              .Where(y => y.Route.StartsWith('/'))
                                              .ToArray();

            if (absoluteRoutes.Length > 0)
            {
                RouteAttribute route = absoluteRoutes.FirstOrDefault(x => x.Route.TrimEnd('/') == url);
                if (route != null)
                {
                    MethodInfo method = methods.ToList().Find(x => x.GetCustomAttribute <RouteAttribute>()?.Route == route.Route);

                    string[] queries = request.Url.Query.TrimStart('?')
                                       .Split('&', StringSplitOptions.RemoveEmptyEntries);

                    object[] parametters = new object[method.GetParameters().Length];
                    parametters = ObtainParametters(method, queries, parametters);
                    object actionValue = ExecuteMethod(method, parametters);

                    OutputResponse(actionValue, request, response);
                    return(true);
                }
                else
                {
                    foreach (RouteAttribute routeAttr in absoluteRoutes)
                    {
                        string attrUrl       = routeAttr.Route;
                        string regexAbsolute = $"{Regex.Replace(attrUrl, @"{(?<name>[a-zA-Z0-9_-]+)}", @"([a-zA-Z0-9_-]+)")}";

                        Match match = Regex.Match(url, regexAbsolute, RegexOptions.IgnoreCase);
                        if (match.Success)
                        {
                            MethodInfo method = methods.ToList().Find(x => x.GetCustomAttribute <RouteAttribute>()?.Route == routeAttr.Route);

                            string[] parameterInfos = method.GetParameters().Select(x => x.Name).ToArray();
                            object[] parametters    = new object[parameterInfos.Length];
                            string[] split          = routeAttr.Route.Split('/', StringSplitOptions.RemoveEmptyEntries);
                            int      i = 1;
                            foreach (var param in split)
                            {
                                int index = Array.FindIndex(parameterInfos, x => $"{{{x}}}" == param);
                                if (index >= 0)
                                {
                                    parametters[index] = request.Url.Segments[i];
                                }
                                i++;
                            }

                            string[] queries = request.Url.Query.TrimStart('?')
                                               .Split('&', StringSplitOptions.RemoveEmptyEntries);
                            parametters = ObtainParametters(method, queries, parametters);
                            object actionValue = ExecuteMethod(method, parametters);

                            OutputResponse(actionValue, request, response);
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }