/// <summary>Clones the routing item.</summary> /// <param name="item">The item.</param> /// <returns></returns> private ApiRoutingItem CloneRoutingItem(ApiRoutingItem item) { var newitem = new ApiRoutingItem { Location = new ApiEndpointLocation( controller: item.Location.Controller, methodInfo: item.Location.MethodInfo, httpMethod: item.Location.HttpMethod, bodyParameterType: item.Location.BodyParameterType, uriParameterType: item.Location.UriParameterType, simpleParameters: item.Location.SimpleParameters, methodReturnType: item.Location.MethodReturnType), Template = item.Template, Configuration = item.Configuration, HttpMethod = item.HttpMethod, RouteVariables = new Dictionary <string, string>() }; return(newitem); }
/// <summary>Adds the route.</summary> /// <param name="registration">The registration.</param> /// <returns></returns> /// <exception cref="Exception"> /// Route '{registration.HttpMethod} {registration.Template}' already has been added. /// or /// Controller must be specified /// or /// </exception> /// <exception cref="MissingMethodException"></exception> public virtual IApiRoutingTable AddRoute(DeepSleepRouteRegistration registration) { if (registration == null) { return(this); } if (registration.Controller == null) { throw new Exception($"{nameof(registration.Controller)} must be specified"); } if (string.IsNullOrWhiteSpace(registration.Endpoint)) { throw new Exception($"{nameof(registration.Endpoint)} must be specified"); } if (registration.HttpMethods?.Where(h => h != null).ToList().Count <= 0) { throw new Exception(string.Format("Http methods not specified on {1}:{0}", registration.Endpoint, registration.Controller.FullName)); } if (registration.Template == null) { throw new Exception($"{nameof(registration.Template)} must be specified"); } var template = registration.Template.Trim(); if (template.StartsWith("/") && template.Length == 1) { template = ""; } else if (template.StartsWith("/")) { template = template.Substring(1); } if (!string.IsNullOrWhiteSpace(this.routePrefix)) { template = (this.routePrefix.EndsWith("/")) ? $"{this.routePrefix}{template}" : $"{this.routePrefix}/{template}"; } foreach (var httpMethod in registration.HttpMethods.Where(h => h != null)) { var existing = this.routes .Where(r => string.Equals(r.Template, template, StringComparison.OrdinalIgnoreCase)) .Where(r => string.Equals(r.HttpMethod, httpMethod.Trim(), StringComparison.OrdinalIgnoreCase)) .FirstOrDefault(); if (existing != null) { throw new Exception($"Route '{httpMethod} {registration.Template}' already has been added."); } MethodInfo methodInfo = registration.MethodInfo; if (methodInfo == null) { try { methodInfo = registration.Controller.GetMethod( name: registration.Endpoint.Trim(), bindingAttr: BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod); } catch (AmbiguousMatchException ex) { throw new Exception($"DeepSleep api routing does not support routes mapped to overloaded methods for api routes. You must rename or move the method for route '[{httpMethod}] {template}'.", ex); } } if (methodInfo == null) { throw new MissingMethodException($"Endpoint '{registration.Endpoint}' does not exist on controller '{registration.Controller.FullName}'"); } var item = new ApiRoutingItem { Template = template, HttpMethod = httpMethod.ToUpperInvariant().Trim(), Configuration = registration.Configuration, Location = new ApiEndpointLocation( controller: Type.GetType(registration.Controller.AssemblyQualifiedName), methodInfo: methodInfo, httpMethod: httpMethod.ToUpperInvariant().Trim()) }; routes.Add(item); } return(this); }