private void MapArgumentsByPosition(Route source, ParameterInfo[] requiredArguments, NameValueCollection headers, int skipNumberOfDestinationArguments, List<KeyValuePair<Type, ParameterNameAndLocation>> map)
        {
            if ((requiredArguments.Length - skipNumberOfDestinationArguments) != source.QueryParameters.Count() + source.RouteParameters.Count())
                throw new InvalidOperationException("Either use parameter names mathing the query and route parameters or specify as many parameters as the combined number of route and query variables");

            IEnumerator headerParameters = headers.AllKeys.GetEnumerator();
            IEnumerator<string> routeParameters = source.RouteParameters.GetEnumerator();
            IEnumerator<string> queryParameters = source.QueryParameters.GetEnumerator();

            foreach (ParameterInfo argument in requiredArguments.Skip(skipNumberOfDestinationArguments))
            {
                if (headerParameters.MoveNext())
                {
                    object value = RouteHelpers.GetHeaderParameterValue((string)headerParameters.Current, headers, argument.ParameterType);

                    if (value != null)
                    {
                        map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType,
                                                                                                                                  new ParameterNameAndLocation { Name = routeParameters.Current, Location = ParameterLocation.Header }));
                    }
                }

                if (routeParameters.MoveNext())
                {
                    map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType,
                                                                                                                              new ParameterNameAndLocation{ Name = routeParameters.Current, Location = ParameterLocation.Route }));
                }
                else
                {
                    queryParameters.MoveNext();
                    map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType,
                                                                                                                              new ParameterNameAndLocation{ Name = queryParameters.Current, Location = ParameterLocation.Query }));
                }
            }
        }
Example #2
0
        public void Matches_NumberOfParametersMatchButNotAllParametersProvided_DoesNotMatch()
        {
            // Arrange
            var route = new Route(new Regex("^/order/(?<id>[^/]+)\\?(?<param0>[^=\\?&]+)=(?<value0>[^&]+)&(?<param1>[^=\\?&]+)=(?<value1>[^&]+)$"), new Dictionary<string, string> { { "id", "id" } }, new List<string> { "foo", "bar" }, "param", "value");

            // Act
            bool matches = route.Matches("/order/1?bar=partner&bar=partner");

            // Assert
            Assert.That(matches, Is.False);
        }
        private List<KeyValuePair<Type, ParameterNameAndLocation>> BuildMap(Route source, Delegate destination, NameValueCollection headers, int skipNumberOfDestinationArguments)
        {
            ParameterInfo[] requiredArguments = destination.Method.GetParameters();
            var map = new List<KeyValuePair<Type, ParameterNameAndLocation>>();

            if (requiredArguments.Length == skipNumberOfDestinationArguments)
                return map;

            bool mappedSuccessfullyByName = MapByArgumentName(source, requiredArguments[skipNumberOfDestinationArguments], headers, map);

            if (mappedSuccessfullyByName)
            {
                foreach (ParameterInfo argument in requiredArguments.Skip(skipNumberOfDestinationArguments + 1))
                    mappedSuccessfullyByName &= MapByArgumentName(source, argument, headers, map);
            }

            if (!mappedSuccessfullyByName)
            {
                map.Clear();
                MapArgumentsByPosition(source, requiredArguments, headers, skipNumberOfDestinationArguments, map);
            }

            return map;
        }
 public MapRequestToDelegateHeuristic(Route source, Delegate destination, int skipNumberOfDestinationArguments = 0)
 {
     _source = source;
     _destination = destination;
     _skipNumberOfDestinationArguments = skipNumberOfDestinationArguments;
 }
        private bool MapByArgumentName(Route source, ParameterInfo argument, NameValueCollection headers, IList<KeyValuePair<Type, ParameterNameAndLocation>> map)
        {
            string argumentName = argument.Name;

            if (headers.AllKeys.Any(key => key.Equals(argumentName, StringComparison.InvariantCultureIgnoreCase)))
            {
                map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType, new ParameterNameAndLocation { Name = argumentName, Location = ParameterLocation.Header }));
                return true;
            }
            else if (source.RouteParameters.Any(parameter => parameter == argumentName))
            {
                map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType, new ParameterNameAndLocation { Name = argumentName, Location = ParameterLocation.Route }));
                return true;
            }
            else if (source.QueryParameters.Any(parameter => parameter == argumentName))
            {
                map.Add(new KeyValuePair<Type, ParameterNameAndLocation>(argument.ParameterType, new ParameterNameAndLocation { Name = argumentName, Location = ParameterLocation.Query }));
                return true;
            }
            return false;
        }