コード例 #1
0
ファイル: Route.cs プロジェクト: mherod/MustardBlack
        public string BuildLocalisedPath(RouteValues values, string regionCode, CultureInfo cultureCode)
        {
            if (this.parsedLocalisedRoute == null)
            {
                throw new InvalidOperationException($"This route `{this.Path}` is not localisable");
            }

            var routeValues = new RouteValues(values);

            routeValues["regionCode"]  = regionCode;
            routeValues["cultureCode"] = cultureCode.Name;

            return(this.parsedLocalisedRoute.BuildPath(routeValues));
        }
コード例 #2
0
ファイル: ParsedRoute.cs プロジェクト: mherod/MustardBlack
        /// <summary>
        ///
        /// </summary>
        /// <param name="userValues"></param>
        /// <returns></returns>
        public string BuildPath(RouteValues userValues)
        {
            userValues = userValues ?? new RouteValues();

            if (this.parameterNames.Any(de => !userValues.ContainsKey(de.Key)))
            {
                log.Error("User route values did not contain a necessary parameter to build path. Url: {url}, User values: {userValues}", this.Url, userValues.Keys);
                return(null);
            }

            var urlBuilder = new StringBuilder();

            int tokensCount = this.tokens.Length - 1;

            for (int i = tokensCount; i >= 0; i--)
            {
                PatternToken token = this.tokens[i];
                if (token == null)
                {
                    if (i < tokensCount && urlBuilder.Length > 0 && urlBuilder[0] != '/')
                    {
                        urlBuilder.Insert(0, '/');
                    }
                    continue;
                }

                if (token.Type == PatternTokenType.Literal)
                {
                    urlBuilder.Insert(0, token.Name);
                    continue;
                }

                var tokenValue = userValues[token.Name];

                if (tokenValue != null)
                {
                    urlBuilder.Insert(0, tokenValue.ToString());
                }
            }

            urlBuilder.Insert(0, '/');
            return(urlBuilder.ToString());
        }
コード例 #3
0
ファイル: Route.cs プロジェクト: mherod/MustardBlack
        public virtual RouteValues GetRouteValues(Url url, HttpMethod method, RequestType requestType)
        {
            if (this.HandledMethods != 0 && (this.HandledMethods & method) != method)
            {
                return(null);
            }

            if (this.RequestTypes != 0 && this.RequestTypes != requestType)
            {
                return(null);
            }

            RouteValues routeValues = null;

            // Check localised route first, otherwise localised wildcard and other routes of the form "/{param}" can accidentally match
            if (this.Localised)
            {
                routeValues = this.parsedLocalisedRoute.Match(url.Path);

                // Simple check to prevent most route collisions with /{regionCode}/{cultureCode}
                // If the regionCode isnt 2 chars, we almost certainly shouldn't be routed here
                var regionCode = (string)routeValues?["regionCode"];
                if (regionCode != null && regionCode.Length != 2)
                {
                    return(null);
                }
            }

            if (routeValues == null)
            {
                routeValues = this.parsedRoute.Match(url.Path);
            }

            if (routeValues != null)
            {
                routeValues["AreaName"] = this.areaName;
            }

            return(routeValues);
        }
コード例 #4
0
ファイル: RouteData.cs プロジェクト: mherod/MustardBlack
 public RouteData(IRoute route, RouteValues values)
 {
     this.Route  = route;
     this.Values = values;
 }
コード例 #5
0
ファイル: ParsedRoute.cs プロジェクト: mherod/MustardBlack
        public RouteValues Match(string path)
        {
            var    ret = new RouteValues();
            string url = this.Url;

            string[] argSegs;
            int      argsCount;

            if (String.IsNullOrEmpty(path))
            {
                argSegs   = null;
                argsCount = 0;
            }
            else
            {
                // TODO: cache indexof
                if (string.Compare(url, path, StringComparison.Ordinal) == 0 && url.IndexOf('{') < 0)
                {
                    return(new RouteValues());
                }

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

            if (argsCount == 1 && String.IsNullOrEmpty(argSegs[0]))
            {
                argsCount = 0;
            }

            if ((this.hasCatchAllSegment && argsCount < this.segmentCount) || (!this.hasCatchAllSegment && argsCount != this.segmentCount))
            {
                return(null);
            }

            int i = 0;

            foreach (PatternSegment segment in this.segments)
            {
                if (i >= argsCount)
                {
                    break;
                }

                if (segment.AllTokensAreLiteral)
                {
                    if (String.Compare(argSegs[i], segment.Tokens[0].Name, StringComparison.OrdinalIgnoreCase) != 0)
                    {
                        return(null);
                    }
                    i++;
                    continue;
                }

                string              pathSegment       = argSegs[i];
                int                 pathSegmentLength = pathSegment != null ? pathSegment.Length : -1;
                int                 pathIndex         = 0;
                PatternTokenType    tokenType;
                List <PatternToken> tokens      = segment.Tokens;
                int                 tokensCount = tokens.Count;

                // Process the path segments ignoring the defaults
                for (int tokenIndex = 0; tokenIndex < tokensCount; tokenIndex++)
                {
                    var token = tokens[tokenIndex];
                    if (pathIndex > pathSegmentLength - 1)
                    {
                        return(null);
                    }

                    tokenType = token.Type;
                    var tokenName = token.Name;

                    // Catch-all
                    if (i > this.segmentCount - 1 || tokenType == PatternTokenType.CatchAll)
                    {
                        if (tokenType != PatternTokenType.CatchAll)
                        {
                            return(null);
                        }

                        StringBuilder sb = new StringBuilder();
                        for (int j = i; j < argsCount; j++)
                        {
                            if (j > i)
                            {
                                sb.Append('/');
                            }
                            sb.Append(argSegs[j]);
                        }

                        ret.Add(tokenName, sb.ToString());
                        break;
                    }

                    // Literal sections
                    if (token.Type == PatternTokenType.Literal)
                    {
                        int nameLen = tokenName.Length;
                        if (pathSegmentLength < nameLen || String.Compare(pathSegment, pathIndex, tokenName, 0, nameLen, StringComparison.OrdinalIgnoreCase) != 0)
                        {
                            return(null);
                        }
                        pathIndex += nameLen;
                        continue;
                    }

                    int nextTokenIndex = tokenIndex + 1;
                    if (nextTokenIndex >= tokensCount)
                    {
                        // Last token
                        ret.Add(tokenName, pathSegment.Substring(pathIndex));
                        continue;
                    }

                    // Next token is a literal - greedy matching. It seems .NET
                    // uses a simple and naive algorithm here which finds the
                    // last ocurrence of the next section literal and assigns
                    // everything before that to this token. See the
                    // GetRouteData28 test in RouteTest.cs
                    var    nextToken     = tokens[nextTokenIndex];
                    string nextTokenName = nextToken.Name;
                    int    lastIndex     = pathSegment.LastIndexOf(nextTokenName, pathSegmentLength - 1, pathSegmentLength - pathIndex, StringComparison.OrdinalIgnoreCase);
                    if (lastIndex == -1)
                    {
                        return(null);
                    }

                    int    copyLength   = lastIndex - pathIndex;
                    string sectionValue = pathSegment.Substring(pathIndex, copyLength);
                    if (String.IsNullOrEmpty(sectionValue))
                    {
                        return(null);
                    }

                    ret.Add(tokenName, sectionValue);
                    pathIndex += copyLength;
                }
                i++;
            }

            if (i < this.segmentCount)
            {
                return(null);
            }

            return(ret);
        }
コード例 #6
0
ファイル: Route.cs プロジェクト: mherod/MustardBlack
        public virtual string BuildPath(RouteValues values = null, bool localised = false)
        {
            var url = localised ? this.parsedLocalisedRoute.BuildPath(values) : this.parsedRoute.BuildPath(values);

            return(url);
        }