public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues) { IList <string> source = RouteParser.SplitUrlToPathSegmentStrings(virtualPath); if (defaultValues == null) { defaultValues = new RouteValueDictionary(); } RouteValueDictionary matchedValues = new RouteValueDictionary(); bool flag = false; bool flag2 = false; for (int i = 0; i < this.PathSegments.Count; i++) { PathSegment segment = this.PathSegments[i]; if (source.Count <= i) { flag = true; } string a = flag ? null : source[i]; if (segment is SeparatorPathSegment) { if (!flag && !string.Equals(a, "/", StringComparison.Ordinal)) { return(null); } } else { ContentPathSegment contentPathSegment = segment as ContentPathSegment; if (contentPathSegment != null) { if (contentPathSegment.IsCatchAll) { this.MatchCatchAll(contentPathSegment, source.Skip <string>(i), defaultValues, matchedValues); flag2 = true; } else if (!this.MatchContentPathSegment(contentPathSegment, a, defaultValues, matchedValues)) { return(null); } } } } if (!flag2 && (this.PathSegments.Count < source.Count)) { for (int j = this.PathSegments.Count; j < source.Count; j++) { if (!RouteParser.IsSeparator(source[j])) { return(null); } } } if (defaultValues != null) { foreach (KeyValuePair <string, object> pair in defaultValues) { if (!matchedValues.ContainsKey(pair.Key)) { matchedValues.Add(pair.Key, pair.Value); } } } return(matchedValues); }
public RouteValueDictionary Match(string virtualPath, RouteValueDictionary defaultValues) { IList <string> requestPathSegments = RouteParser.SplitUrlToPathSegmentStrings(virtualPath); if (defaultValues == null) { defaultValues = new RouteValueDictionary(); } RouteValueDictionary matchedValues = new RouteValueDictionary(); // This flag gets set once all the data in the URL has been parsed through, but // the route we're trying to match against still has more parts. At this point // we'll only continue matching separator characters and parameters that have // default values. bool ranOutOfStuffToParse = false; // This value gets set once we start processing a catchall parameter (if there is one // at all). Once we set this value we consume all remaining parts of the URL into its // parameter value. bool usedCatchAllParameter = false; for (int i = 0; i < PathSegments.Count; i++) { PathSegment pathSegment = PathSegments[i]; if (requestPathSegments.Count <= i) { ranOutOfStuffToParse = true; } string requestPathSegment = ranOutOfStuffToParse ? null : requestPathSegments[i]; if (pathSegment is SeparatorPathSegment) { if (ranOutOfStuffToParse) { // If we're trying to match a separator in the route but there's no more content, that's OK } else { if (!String.Equals(requestPathSegment, "/", StringComparison.Ordinal)) { return(null); } } } else { ContentPathSegment contentPathSegment = pathSegment as ContentPathSegment; if (contentPathSegment != null) { if (contentPathSegment.IsCatchAll) { Debug.Assert(i == (PathSegments.Count - 1), "If we're processing a catch-all, we should be on the last route segment."); MatchCatchAll(contentPathSegment, requestPathSegments.Skip(i), defaultValues, matchedValues); usedCatchAllParameter = true; } else { if (!MatchContentPathSegment(contentPathSegment, requestPathSegment, defaultValues, matchedValues)) { return(null); } } } else { Debug.Fail("Invalid path segment type"); } } } if (!usedCatchAllParameter) { if (PathSegments.Count < requestPathSegments.Count) { // If we've already gone through all the parts defined in the route but the URL // still contains more content, check that the remaining content is all separators. for (int i = PathSegments.Count; i < requestPathSegments.Count; i++) { if (!RouteParser.IsSeparator(requestPathSegments[i])) { return(null); } } } } // Copy all remaining default values to the route data if (defaultValues != null) { foreach (var defaultValue in defaultValues) { if (!matchedValues.ContainsKey(defaultValue.Key)) { matchedValues.Add(defaultValue.Key, defaultValue.Value); } } } return(matchedValues); }