예제 #1
0
        private BoundUrl BuildUrl(ValueDictionary defaults,
                                  ValueDictionary acceptedValues, HashSet <string> unusedValues)
        {
            StringBuilder pathBuilder    = new StringBuilder();
            StringBuilder segmentBuilder = new StringBuilder();
            bool          flush          = false;

            foreach (PathSegment segment in _segments)
            {
                SeparatorSegment separator = (segment as SeparatorSegment);
                ContentSegment   content   = (segment as ContentSegment);

                if (separator != null)
                {
                    if (flush && segmentBuilder.Length > 0)
                    {
                        pathBuilder.Append(segmentBuilder.ToString());
                        segmentBuilder.Length = 0;
                    }

                    flush = false;
                    segmentBuilder.Append(RouteParser.PathSeparator);
                }

                if (content != null)
                {
                    bool segmentEnd = false;

                    foreach (PathSubsegment subsegment in content.Segments)
                    {
                        LiteralSubsegment   literal   = (subsegment as LiteralSubsegment);
                        ParameterSubsegment parameter = (subsegment as ParameterSubsegment);

                        if (literal != null)
                        {
                            flush = true;
                            segmentBuilder.Append(Uri.EscapeUriString(literal.Literal));
                        }

                        if (parameter != null)
                        {
                            object acceptedValue;
                            object defaultValue;

                            if (flush && segmentBuilder.Length > 0)
                            {
                                pathBuilder.Append(segmentBuilder.ToString());
                                segmentBuilder.Length = 0;

                                segmentEnd = true;
                            }

                            flush = false;

                            if (acceptedValues.TryGetValue(parameter.ParameterName, out acceptedValue))
                            {
                                unusedValues.Remove(parameter.ParameterName);
                            }

                            defaults.TryGetValue(parameter.ParameterName, out defaultValue);
                            if (RoutePartsEqual(acceptedValue, defaultValue))
                            {
                                segmentBuilder.Append(Uri.EscapeUriString(
                                                          Convert.ToString(acceptedValue, CultureInfo.InvariantCulture)));
                                continue;
                            }

                            if (segmentBuilder.Length > 0)
                            {
                                pathBuilder.Append(segmentBuilder.ToString());
                                segmentBuilder.Length = 0;
                            }

                            pathBuilder.Append(Uri.EscapeUriString(Convert.ToString(acceptedValue, CultureInfo.InvariantCulture)));
                            segmentEnd = true;
                        }
                    }

                    if (segmentEnd && segmentBuilder.Length > 0)
                    {
                        pathBuilder.Append(segmentBuilder.ToString());
                        segmentBuilder.Length = 0;
                    }
                }
            }

            if (flush && segmentBuilder.Length > 0)
            {
                pathBuilder.Append(segmentBuilder.ToString());
            }

            if (unusedValues.Count > 0)
            {
                bool isFirst = true;
                foreach (string key in unusedValues)
                {
                    object value;
                    if (acceptedValues.TryGetValue(key, out value))
                    {
                        pathBuilder.Append(isFirst ? '?' : '&');
                        isFirst = false;

                        pathBuilder.Append(Uri.EscapeDataString(key.ToLowerInvariant()));
                        pathBuilder.Append('=');
                        pathBuilder.Append(Uri.EscapeDataString(
                                               Convert.ToString(value, CultureInfo.InvariantCulture)));
                    }
                }
            }
            return(new BoundUrl(pathBuilder.ToString(), acceptedValues));
        }
예제 #2
0
        public ValueDictionary Match(string virtualPath,
                                     ValueDictionary variables, ValueDictionary defaults)
        {
            List <string> parts = new List <string>(RouteParser.SplitUrl(virtualPath));

            defaults  = defaults ?? new ValueDictionary();
            variables = variables ?? new ValueDictionary();

            ValueDictionary values = new ValueDictionary();

            bool hasAdditionalParameters = false;
            bool isCatchAll = false;

            AssignVariableValues(variables);

            for (int i = 0; i < _segments.Count; i++)
            {
                SeparatorSegment separator = (_segments[i] as SeparatorSegment);
                ContentSegment   content   = (_segments[i] as ContentSegment);

                if (parts.Count <= i)
                {
                    hasAdditionalParameters = true;
                }

                string part = (hasAdditionalParameters) ? null : parts[i];
                if (separator != null)
                {
                    if (!hasAdditionalParameters &&
                        !RouteParser.IsSeparator(part))
                    {
                        return(null);
                    }
                }

                if (content != null)
                {
                    if (content.IsCatchAll)
                    {
                        MatchCatchAll(content, parts.Skip(i), defaults, values);
                        isCatchAll = true;
                    }
                    else if (!MatchContent(content, part, defaults, values))
                    {
                        return(null);
                    }
                }
            }

            if (!isCatchAll && _segments.Count < parts.Count)
            {
                for (int j = _segments.Count; j < parts.Count; j++)
                {
                    if (!RouteParser.IsSeparator(parts[j]))
                    {
                        return(null);
                    }
                }
            }

            if (defaults != null)
            {
                foreach (KeyValuePair <string, object> kvp in defaults)
                {
                    if (!values.ContainsKey(kvp.Key))
                    {
                        values.Add(kvp.Key, kvp.Value);
                    }
                }
            }

            return(values);
        }