public virtual IHttpRouteData GetRouteData( string virtualPathRoot, HttpRequestMessage request ) { if (virtualPathRoot == null) { throw Error.ArgumentNull("virtualPathRoot"); } if (request == null) { throw Error.ArgumentNull("request"); } RoutingContext context = GetOrCreateRoutingContext(virtualPathRoot, request); if (!context.IsValid) { return(null); } HttpRouteValueDictionary values = ParsedRoute.Match(context, _defaults); if (values == null) { // If we got back a null value set, that means the URI did not match return(null); } // Validate the values if (!ProcessConstraints(request, values, HttpRouteDirection.UriResolution)) { return(null); } return(new HttpRouteData(this, values)); }
public HttpRouteValueDictionary Match(RoutingContext context, HttpRouteValueDictionary defaultValues) { List<string> requestPathSegments = context.PathSegments; if (defaultValues == null) { defaultValues = new HttpRouteValueDictionary(); } HttpRouteValueDictionary matchedValues = new HttpRouteValueDictionary(); // This flag gets set once all the data in the URI 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 URI 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 PathSeparatorSegment) { 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 { PathContentSegment contentPathSegment = pathSegment as PathContentSegment; if (contentPathSegment != null) { if (contentPathSegment.IsCatchAll) { Contract.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 { Contract.Assert(false, "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 URI // 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; }
public HttpRouteValueDictionary Match(RoutingContext context, HttpRouteValueDictionary defaultValues) { List <string> requestPathSegments = context.PathSegments; if (defaultValues == null) { defaultValues = new HttpRouteValueDictionary(); } HttpRouteValueDictionary matchedValues = new HttpRouteValueDictionary(); // This flag gets set once all the data in the URI 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 URI 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 PathSeparatorSegment) { 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 { PathContentSegment contentPathSegment = pathSegment as PathContentSegment; if (contentPathSegment != null) { if (contentPathSegment.IsCatchAll) { Contract.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 { Contract.Assert(false, "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 URI // 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); }