/// <summary> /// Attempts to matche given route values to this parsed route, building up a probable path that /// could be used to navigate to this route. /// </summary> /// <param name="route">The route.</param> /// <param name="values">The values.</param> /// <returns> /// An object indicating the success or failure of the attempt to match the path. /// </returns> public PathMatch MatchRouteToPath(IRoute route, RouteValueDictionary values) { var valueBag = new RouteValueBag(values); var segmentValues = new List <object>(); foreach (var segment in Segments) { var match = segment.MatchValues(route, valueBag); if (match.Success) { segmentValues.Add(match.SegmentValue); } else { return(PathMatch.Failure(route, match.FailReason)); } } var allValues = new RouteValueDictionary(Defaults); allValues.AddRange(values, true); allValues.AddRange(values, true); var leftOver = valueBag.GetRemaining(); foreach (var leftOverItem in leftOver) { var key = leftOverItem.Key; if (Defaults.ContainsKey(key)) { var leftOverValue = leftOverItem.Value; var defaultValue = Defaults[leftOverItem.Key]; if ((leftOverValue == null || defaultValue == null) && (leftOverValue != defaultValue) || (leftOverValue != null && !leftOverValue.Equals(defaultValue))) { return(PathMatch.Failure(route, string.Format("The route was a close match, but the value of the '{0}' parameter was expected to be '{1}', but '{2}' was provided instead.", key, defaultValue, leftOverValue))); } } } if (leftOver.Count > 0) { foreach (var defaultItem in Defaults.Where(item => leftOver.ContainsKey(item.Key))) { leftOver.Remove(defaultItem.Key); } } return(PathMatch.Successful(route, allValues, leftOver, segmentValues)); }
/// <summary> /// Attempts to matche a path to this parsed route. /// </summary> /// <param name="route">The route.</param> /// <param name="request">The request.</param> /// <returns>An object indicating the success or failure of the attempt to match the path.</returns> public RouteMatch MatchPathToRoute(IRoute route, string request) { var values = new RouteValueDictionary(); var iterator = new PathIterator(request); foreach (var segment in Segments) { var match = segment.MatchPath(route, iterator); if (match.Success) { values.AddRange(match.Values); } else { return(RouteMatch.Failure(route, match.FailReason)); } } return(iterator.IsAtEnd ? RouteMatch.Successful(route, values) : RouteMatch.Failure(route, "Route was initially matched, but the request contains additional unexpected segments")); }
/// <summary> /// Attempts to matche a path to this parsed route. /// </summary> /// <param name="route">The route.</param> /// <param name="request">The request.</param> /// <returns>An object indicating the success or failure of the attempt to match the path.</returns> public RouteMatch MatchPathToRoute(IRoute route, string request) { var values = new RouteValueDictionary(); var iterator = new PathIterator(request); foreach (var segment in Segments) { var match = segment.MatchPath(route, iterator); if (match.Success) { values.AddRange(match.Values); } else { return RouteMatch.Failure(route, match.FailReason); } } return iterator.IsAtEnd ? RouteMatch.Successful(route, values) : RouteMatch.Failure(route, "Route was initially matched, but the request contains additional unexpected segments"); }
/// <summary> /// Navigates to the specified URI, resolving the first matching route. /// </summary> /// <param name="requestUri">The request URI.</param> /// <param name="additionalData">Additional data (like post data) that is not in the URI but is used /// for navigation.</param> private void ExecuteRequestWithUri(Uri requestUri, RouteValueDictionary additionalData) { additionalData = additionalData ?? new RouteValueDictionary(); var path = requestUri.GetComponents(UriComponents.Host | UriComponents.Path, UriFormat.Unescaped); var queryString = requestUri.GetComponents(UriComponents.Query, UriFormat.Unescaped); var route = _routes.MatchPathToRoute(path); if (!route.Success) { throw new UnroutableRequestException(string.Format("The request URI '{0}' could not be routed. {1}{2}", requestUri, Environment.NewLine, route.FailReason)); } // Create a value dictionary with all of the known information - post data, query string data, // and data extracted from the route. We'll use this for the navigation request. var data = new RouteValueDictionary(additionalData); data.AddRange(route.Values, true); var queryValues = new QueryValueCollection(queryString); foreach (var pair in queryValues) { if (!data.ContainsKey(pair.Key)) { data[pair.Key] = pair.Value; } } var handler = route.Route.CreateRouteHandler(); handler.ProcessRequest( new ResolvedNavigationRequest( requestUri, path, additionalData.Count > 0, this, route.Route, data, _progressListeners.Union(Factory.ProgressListeners ?? new NavigationProgressListenerCollection()).ToList() )); }
/// <summary> /// Attempts to matche given route values to this parsed route, building up a probable path that /// could be used to navigate to this route. /// </summary> /// <param name="route">The route.</param> /// <param name="values">The values.</param> /// <returns> /// An object indicating the success or failure of the attempt to match the path. /// </returns> public PathMatch MatchRouteToPath(IRoute route, RouteValueDictionary values) { var valueBag = new RouteValueBag(values); var segmentValues = new List<object>(); foreach (var segment in Segments) { var match = segment.MatchValues(route, valueBag); if (match.Success) { segmentValues.Add(match.SegmentValue); } else { return PathMatch.Failure(route, match.FailReason); } } var allValues = new RouteValueDictionary(Defaults); allValues.AddRange(values, true); allValues.AddRange(values, true); var leftOver = valueBag.GetRemaining(); foreach (var leftOverItem in leftOver) { var key = leftOverItem.Key; if (Defaults.ContainsKey(key)) { var leftOverValue = leftOverItem.Value; var defaultValue = Defaults[leftOverItem.Key]; if ((leftOverValue == null || defaultValue == null) && (leftOverValue != defaultValue) || (leftOverValue != null && !leftOverValue.Equals(defaultValue))) { return PathMatch.Failure(route, string.Format("The route was a close match, but the value of the '{0}' parameter was expected to be '{1}', but '{2}' was provided instead.", key, defaultValue, leftOverValue)); } } } if (leftOver.Count > 0) { foreach (var defaultItem in Defaults.Where(item => leftOver.ContainsKey(item.Key))) { leftOver.Remove(defaultItem.Key); } } return PathMatch.Successful(route, allValues, leftOver, segmentValues); }
public void ShouldNotOverrideAddItemsWhenToldNotTo() { var original = new RouteValueDictionary(new { foo = "1", abc = "3" }); var replacement = new RouteValueDictionary(new { foo = "2", abc = "4", def = "6" }); original.AddRange(replacement, false); Assert.AreEqual("1", original["foo"]); Assert.AreEqual("3", original["abc"]); Assert.AreEqual("6", original["def"]); }
public void CannotAddRangeSelf() { var parameters = new RouteValueDictionary(); Assert.Throws<InvalidOperationException>(() => parameters.AddRange(parameters)); }
public void ShouldIgnoreNullAddRange() { var original = new RouteValueDictionary(new { foo = "1", abc = "3" }); original.AddRange(null); }