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