System.Web.Routing.PatternParser.Match C# (CSharp) Method

Match() public method

public Match ( string path, RouteValueDictionary defaults ) : RouteValueDictionary
path string
defaults RouteValueDictionary
return RouteValueDictionary
		public RouteValueDictionary Match (string path, RouteValueDictionary defaults)
		{
			var ret = new RouteValueDictionary ();
			string url = Url;
			string [] argSegs;
			int argsCount;
			
			if (String.IsNullOrEmpty (path)) {
				argSegs = null;
				argsCount = 0;
			} else {
				// quick check
				if (String.Compare (url, path, StringComparison.Ordinal) == 0 && url.IndexOf ('{') < 0)
					return AddDefaults (ret, defaults);

				argSegs = path.Split ('/');
				argsCount = argSegs.Length;

				if (String.IsNullOrEmpty (argSegs [argsCount - 1]))
					argsCount--; // path ends with a trailinig '/'
			}
			bool haveDefaults = defaults != null && defaults.Count > 0;

			if (argsCount == 1 && String.IsNullOrEmpty (argSegs [0]))
				argsCount = 0;
			
			if (!haveDefaults && ((haveSegmentWithCatchAll && argsCount < segmentCount) || (!haveSegmentWithCatchAll && argsCount != segmentCount)))
				return null;

			int i = 0;

			foreach (PatternSegment segment in segments) {
				if (i >= argsCount)
					break;
				
				if (segment.AllLiteral) {
					if (String.Compare (argSegs [i], segment.Tokens [0].Name, StringComparison.OrdinalIgnoreCase) != 0)
						return null;
					i++;
					continue;
				}

				if (!MatchSegment (i, argsCount, argSegs, segment.Tokens, ret))
					return null;
				i++;
			}

			// Check the remaining segments, if any, and see if they are required
			//
			// If a segment has more than one section (i.e. there's at least one
			// literal, then it cannot match defaults
			//
			// All of the remaining segments must have all defaults provided and they
			// must not be literals or the match will fail.
			if (i < segmentCount) {
				if (!haveDefaults)
					return null;
				
				for (;i < segmentCount; i++) {
					var segment = segments [i];
					if (segment.AllLiteral)
						return null;
					
					var tokens = segment.Tokens;
					if (tokens.Count != 1)
						return null;

					if (!defaults.ContainsKey (tokens [0].Name))
						return null;
				}
			} else if (!haveSegmentWithCatchAll && argsCount > segmentCount)
				return null;
			
			return AddDefaults (ret, defaults);
		}
		

Usage Example

Example #1
0
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            var path     = httpContext.Request.AppRelativeCurrentExecutionFilePath;
            var pathInfo = httpContext.Request.PathInfo;

            if (!String.IsNullOrEmpty(pathInfo))
            {
                path += pathInfo;
            }

            // probably code like this causes ArgumentOutOfRangeException under .NET.
            // It somehow allows such path that is completely equivalent to the Url. Dunno why.
            if (Url != path && path.Substring(0, 2) != "~/")
            {
                return(null);
            }
            path = path.Substring(2);

            var values = url.Match(path, Defaults);

            if (values == null)
            {
                return(null);
            }

            RouteValueDictionary constraints = Constraints;

            if (constraints != null)
            {
                foreach (var p in constraints)
                {
                    if (!ProcessConstraint(httpContext, p.Value, p.Key, values, RouteDirection.IncomingRequest))
                    {
                        return(null);
                    }
                }
            }

            var rd = new RouteData(this, RouteHandler);
            RouteValueDictionary rdValues = rd.Values;

            foreach (var p in values)
            {
                rdValues.Add(p.Key, p.Value);
            }

            RouteValueDictionary dataTokens = DataTokens;

            if (dataTokens != null)
            {
                RouteValueDictionary rdDataTokens = rd.DataTokens;
                foreach (var token in dataTokens)
                {
                    rdDataTokens.Add(token.Key, token.Value);
                }
            }

            return(rd);
        }