Esempio n. 1
0
 private static void AddUndeclaredRouteParameters(HttpParsedRoute parsedRoute, IDictionary <string, object> routeDefaults, IList <ApiParameterDescription> parameterDescriptions)
 {
     foreach (PathSegment path in parsedRoute.PathSegments)
     {
         PathContentSegment content = path as PathContentSegment;
         if (content != null)
         {
             foreach (PathSubsegment subSegment in content.Subsegments)
             {
                 PathParameterSubsegment parameter = subSegment as PathParameterSubsegment;
                 if (parameter != null)
                 {
                     object parameterValue;
                     string parameterName = parameter.ParameterName;
                     if (!parameterDescriptions.Any(p => String.Equals(p.Name, parameterName, StringComparison.OrdinalIgnoreCase)) &&
                         (!routeDefaults.TryGetValue(parameterName, out parameterValue) ||
                          parameterValue != RouteParameter.Optional))
                     {
                         parameterDescriptions.Add(
                             new ApiParameterDescription
                         {
                             Name   = parameterName,
                             Source = ApiParameterSource.FromUri
                         });
                     }
                 }
             }
         }
     }
 }
Esempio n. 2
0
        private static bool TryExpandUriParameters(IHttpRoute route, string routeTemplate, ICollection <ApiParameterDescription> parameterDescriptions, out string expandedRouteTemplate)
        {
            HttpParsedRoute             parsedRoute             = HttpRouteParser.Parse(routeTemplate);
            Dictionary <string, object> parameterValuesForRoute = new Dictionary <string, object>();

            foreach (ApiParameterDescription parameterDescriptor in parameterDescriptions)
            {
                Type parameterType = parameterDescriptor.ParameterDescriptor.ParameterType;
                if (parameterDescriptor.Source == ApiParameterSource.FromUri && TypeHelper.IsSimpleUnderlyingType(parameterType))
                {
                    parameterValuesForRoute.Add(parameterDescriptor.Name, "{" + parameterDescriptor.Name + "}");
                }
            }

            BoundRouteTemplate boundRouteTemplate = parsedRoute.Bind(null, parameterValuesForRoute, new HttpRouteValueDictionary(route.Defaults), new HttpRouteValueDictionary(route.Constraints));

            if (boundRouteTemplate == null)
            {
                expandedRouteTemplate = null;
                return(false);
            }

            expandedRouteTemplate = Uri.UnescapeDataString(boundRouteTemplate.BoundTemplate);
            return(true);
        }
Esempio n. 3
0
        private static int Compare(RouteEntry entry1, RouteEntry entry2)
#endif
        {
#if ASPNETWEBAPI
            HttpParsedRoute parsedRoute1 = entry1.ParsedRoute;
            HttpParsedRoute parsedRoute2 = entry2.ParsedRoute;
#else
            ParsedRoute parsedRoute1 = entry1.ParsedRoute;
            ParsedRoute parsedRoute2 = entry2.ParsedRoute;
#endif

            IList <PathContentSegment> segments1 = parsedRoute1.PathSegments.OfType <PathContentSegment>().ToArray();
            IList <PathContentSegment> segments2 = parsedRoute2.PathSegments.OfType <PathContentSegment>().ToArray();

            for (int i = 0; i < segments1.Count && i < segments2.Count; i++)
            {
                PathContentSegment segment1 = segments1[i];
                PathContentSegment segment2 = segments2[i];

                int order1 = GetOrder(segment1, entry1.Route.Constraints);
                int order2 = GetOrder(segment2, entry2.Route.Constraints);

                if (order1 > order2)
                {
                    return(1);
                }
                else if (order1 < order2)
                {
                    return(-1);
                }
            }

            return(0);
        }
Esempio n. 4
0
        private void PopulateActionDescriptions(HttpActionDescriptor actionDescriptor, IHttpRoute route, string localPath, Collection <ApiDescription> apiDescriptions)
        {
            string apiDocumentation = GetApiDocumentation(actionDescriptor);

            HttpParsedRoute parsedRoute = RouteParser.Parse(localPath);

            // parameters
            IList <ApiParameterDescription> parameterDescriptions = CreateParameterDescriptions(actionDescriptor, parsedRoute, route.Defaults);

            // expand all parameter variables
            string finalPath;

            if (!TryExpandUriParameters(route, parsedRoute, parameterDescriptions, out finalPath))
            {
                // the action cannot be reached due to parameter mismatch, e.g. routeTemplate = "/users/{name}" and GetUsers(id)
                return;
            }

            // request formatters
            ApiParameterDescription          bodyParameter = parameterDescriptions.FirstOrDefault(description => description.Source == ApiParameterSource.FromBody);
            IEnumerable <MediaTypeFormatter> supportedRequestBodyFormatters = bodyParameter != null?
                                                                              actionDescriptor.Configuration.Formatters.Where(f => f.CanReadType(bodyParameter.ParameterDescriptor.ParameterType)) :
                                                                                  Enumerable.Empty <MediaTypeFormatter>();

            // response formatters
            ResponseDescription responseDescription = CreateResponseDescription(actionDescriptor);
            Type returnType = responseDescription.ResponseType ?? responseDescription.DeclaredType;
            IEnumerable <MediaTypeFormatter> supportedResponseFormatters = (returnType != null && returnType != typeof(void)) ?
                                                                           actionDescriptor.Configuration.Formatters.Where(f => f.CanWriteType(returnType)) :
                                                                           Enumerable.Empty <MediaTypeFormatter>();

            // Replacing the formatter tracers with formatters if tracers are present.
            supportedRequestBodyFormatters = GetInnerFormatters(supportedRequestBodyFormatters);
            supportedResponseFormatters    = GetInnerFormatters(supportedResponseFormatters);

            // get HttpMethods supported by an action. Usually there is one HttpMethod per action but we allow multiple of them per action as well.
            IList <HttpMethod> supportedMethods = GetHttpMethodsSupportedByAction(route, actionDescriptor);

            foreach (HttpMethod method in supportedMethods)
            {
                apiDescriptions.Add(new ApiDescription
                {
                    Documentation                  = apiDocumentation,
                    HttpMethod                     = method,
                    RelativePath                   = finalPath,
                    ActionDescriptor               = actionDescriptor,
                    Route                          = route,
                    SupportedResponseFormatters    = new Collection <MediaTypeFormatter>(supportedResponseFormatters.ToList()),
                    SupportedRequestBodyFormatters = new Collection <MediaTypeFormatter>(supportedRequestBodyFormatters.ToList()),
                    ParameterDescriptions          = new Collection <ApiParameterDescription>(parameterDescriptions),
                    ResponseDescription            = responseDescription
                });
            }
        }
        private static decimal Compute(string template)
        {
            DefaultInlineConstraintResolver resolver    = new DefaultInlineConstraintResolver();
            HttpRouteValueDictionary        defaults    = new HttpRouteValueDictionary();
            HttpRouteValueDictionary        constraints = new HttpRouteValueDictionary();
            string standardRouteTemplate = InlineRouteTemplateParser.ParseRouteTemplate(template,
                                                                                        defaults, constraints, new DefaultInlineConstraintResolver());
            HttpParsedRoute parsedRoute = HttpRouteParser.Parse(standardRouteTemplate);

            return(RoutePrecedence.Compute(parsedRoute, constraints));
        }
Esempio n. 6
0
        // Set as internal for the unit test.
        internal static bool TryExpandUriParameters(IHttpRoute route, HttpParsedRoute parsedRoute, ICollection <ApiParameterDescription> parameterDescriptions, out string expandedRouteTemplate)
        {
            Dictionary <string, object> parameterValuesForRoute = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
            bool   emitPrefixes = ShouldEmitPrefixes(parameterDescriptions);
            string prefix       = String.Empty;

            foreach (ApiParameterDescription parameterDescriptor in parameterDescriptions)
            {
                if (parameterDescriptor.Source == ApiParameterSource.FromUri)
                {
                    if (parameterDescriptor.ParameterDescriptor == null ||
                        (parameterDescriptor.ParameterDescriptor != null &&
                         TypeHelper.CanConvertFromString(parameterDescriptor.ParameterDescriptor.ParameterType)))
                    {
                        if (!parameterValuesForRoute.ContainsKey(parameterDescriptor.Name))
                        {
                            parameterValuesForRoute.Add(parameterDescriptor.Name, "{" + parameterDescriptor.Name + "}");
                        }
                    }
                    else if (parameterDescriptor.ParameterDescriptor != null &&
                             parameterDescriptor.CanConvertPropertiesFromString())
                    {
                        if (emitPrefixes)
                        {
                            prefix = parameterDescriptor.Name + ".";
                        }

                        // Inserting the individual properties of the object in the query string
                        // as all the complex object can not be converted from string, but all its
                        // individual properties can.
                        foreach (PropertyInfo property in parameterDescriptor.GetBindableProperties())
                        {
                            string queryParameterName = prefix + property.Name;
                            if (!parameterValuesForRoute.ContainsKey(queryParameterName))
                            {
                                parameterValuesForRoute.Add(queryParameterName, "{" + queryParameterName + "}");
                            }
                        }
                    }
                }
            }

            BoundRouteTemplate boundRouteTemplate = parsedRoute.Bind(null, parameterValuesForRoute, new HttpRouteValueDictionary(route.Defaults), new HttpRouteValueDictionary(route.Constraints));

            if (boundRouteTemplate == null)
            {
                expandedRouteTemplate = null;
                return(false);
            }

            expandedRouteTemplate = Uri.UnescapeDataString(boundRouteTemplate.BoundTemplate);
            return(true);
        }
Esempio n. 7
0
        private IList <ApiParameterDescription> CreateParameterDescriptions(
            HttpActionDescriptor actionDescriptor,
            HttpParsedRoute parsedRoute,
            IDictionary <string, object> routeDefaults
            )
        {
            IList <ApiParameterDescription> parameterDescriptions =
                new List <ApiParameterDescription>();
            HttpActionBinding actionBinding = GetActionBinding(actionDescriptor);

            // try get parameter binding information if available
            if (actionBinding != null)
            {
                HttpParameterBinding[] parameterBindings = actionBinding.ParameterBindings;
                if (parameterBindings != null)
                {
                    foreach (HttpParameterBinding parameter in parameterBindings)
                    {
                        parameterDescriptions.Add(CreateParameterDescriptionFromBinding(parameter));
                    }
                }
            }
            else
            {
                Collection <HttpParameterDescriptor> parameters = actionDescriptor.GetParameters();
                if (parameters != null)
                {
                    foreach (HttpParameterDescriptor parameter in parameters)
                    {
                        parameterDescriptions.Add(
                            CreateParameterDescriptionFromDescriptor(parameter)
                            );
                    }
                }
            }

            // Adding route parameters not declared on the action. We're doing this because route parameters may or
            // may not be part of the action parameters and we want to have them in the description.
            AddUndeclaredRouteParameters(parsedRoute, routeDefaults, parameterDescriptions);

            return(parameterDescriptions);
        }
Esempio n. 8
0
        // Set as internal for the unit test.
        internal static bool TryExpandUriParameters(IHttpRoute route, HttpParsedRoute parsedRoute, ICollection <ApiParameterDescription> parameterDescriptions, out string expandedRouteTemplate)
        {
            Dictionary <string, object> parameterValuesForRoute = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);
            bool   emitPrefixes = ShouldEmitPrefixes(parameterDescriptions);
            string prefix       = String.Empty;

            foreach (ApiParameterDescription parameterDescription in parameterDescriptions)
            {
                if (parameterDescription.Source == ApiParameterSource.FromUri)
                {
                    if (parameterDescription.ParameterDescriptor == null)
                    {
                        // Undeclared route parameter handling generates query string like
                        // "?name={name}"
                        AddPlaceholder(parameterValuesForRoute, parameterDescription.Name);
                    }
                    else if (TypeHelper.CanConvertFromString(parameterDescription.ParameterDescriptor.ParameterType))
                    {
                        // Simple type generates query string like
                        // "?name={name}"
                        AddPlaceholder(parameterValuesForRoute, parameterDescription.Name);
                    }
                    else if (IsBindableCollection(parameterDescription.ParameterDescriptor.ParameterType))
                    {
                        string parameterName = parameterDescription.ParameterDescriptor.ParameterName;
                        Type   innerType     =
                            GetCollectionElementType(parameterDescription.ParameterDescriptor.ParameterType);
                        PropertyInfo[] innerTypeProperties =
                            ApiParameterDescription.GetBindableProperties(innerType).ToArray();
                        if (innerTypeProperties.Any())
                        {
                            // Complex array and collection generate query string like
                            // "?name[0].foo={name[0].foo}&name[0].bar={name[0].bar}
                            //  &name[1].foo={name[1].foo}&name[1].bar={name[1].bar}"
                            AddPlaceholderForProperties(parameterValuesForRoute,
                                                        innerTypeProperties,
                                                        parameterName + "[0].");
                            AddPlaceholderForProperties(parameterValuesForRoute,
                                                        innerTypeProperties,
                                                        parameterName + "[1].");
                        }
                        else
                        {
                            // Simple array and collection generate query string like
                            // "?name[0]={name[0]}&name[1]={name[1]}".
                            AddPlaceholder(parameterValuesForRoute, parameterName + "[0]");
                            AddPlaceholder(parameterValuesForRoute, parameterName + "[1]");
                        }
                    }
                    else if (IsBindableKeyValuePair(parameterDescription.ParameterDescriptor.ParameterType))
                    {
                        // KeyValuePair generates query string like
                        // "?key={key}&value={value}"
                        AddPlaceholder(parameterValuesForRoute, "key");
                        AddPlaceholder(parameterValuesForRoute, "value");
                    }
                    else if (IsBindableDictionry(parameterDescription.ParameterDescriptor.ParameterType))
                    {
                        // Dictionary generates query string like
                        // "?dict[0].key={dict[0].key}&dict[0].value={dict[0].value}
                        //  &dict[1].key={dict[1].key}&dict[1].value={dict[1].value}"
                        string parameterName = parameterDescription.ParameterDescriptor.ParameterName;
                        AddPlaceholder(parameterValuesForRoute, parameterName + "[0].key");
                        AddPlaceholder(parameterValuesForRoute, parameterName + "[0].value");
                        AddPlaceholder(parameterValuesForRoute, parameterName + "[1].key");
                        AddPlaceholder(parameterValuesForRoute, parameterName + "[1].value");
                    }
                    else if (parameterDescription.CanConvertPropertiesFromString())
                    {
                        if (emitPrefixes)
                        {
                            prefix = parameterDescription.Name + ".";
                        }

                        // Inserting the individual properties of the object in the query string
                        // as all the complex object can not be converted from string, but all its
                        // individual properties can.
                        AddPlaceholderForProperties(parameterValuesForRoute,
                                                    parameterDescription.GetBindableProperties(),
                                                    prefix);
                    }
                }
            }

            BoundRouteTemplate boundRouteTemplate = parsedRoute.Bind(null, parameterValuesForRoute, new HttpRouteValueDictionary(route.Defaults), new HttpRouteValueDictionary(route.Constraints));

            if (boundRouteTemplate == null)
            {
                expandedRouteTemplate = null;
                return(false);
            }

            expandedRouteTemplate = Uri.UnescapeDataString(boundRouteTemplate.BoundTemplate);
            return(true);
        }