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(); } }
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; }
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); }