예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }