예제 #1
0
        private static RouteResolutionResult FindMostSpecificRoute(IEnumerable <RouteResolutionResult> routes)
        {
            RouteResolutionResult bestMatch = default(RouteResolutionResult);
            var otherMatches = new List <RouteResolutionResult>();

            foreach (var route in routes)
            {
                if (bestMatch == null)
                {
                    bestMatch = route;
                    continue;
                }

                if (route.VariableCount > bestMatch.VariableCount)
                {
                    otherMatches.Clear();
                    bestMatch = route;
                    continue;
                }

                if (route.Priority < bestMatch.Priority)
                {
                    continue;
                }

                if (route.VariableCount == bestMatch.VariableCount)
                {
                    // Choose
                    //     /product-lines/{productId}/{lineNumber}
                    // over
                    //     /products/{productId}/product-lines/{lineNumber}
                    // (shortest one)
                    if (route.PathLength < bestMatch.PathLength)
                    {
                        otherMatches.Add(bestMatch);
                        bestMatch = route;
                    }
                    else
                    {
                        otherMatches.Add(route);
                    }
                }
            }

            // We may find several different routes {code}/{id} and {code}/{name} having the same number of variables.
            // Such case will be handled by the next check.
            return(bestMatch == null || otherMatches.All(r => r.HasSameVariables(bestMatch))
                ? bestMatch
                : null);
        }
예제 #2
0
        public RouteResolutionResult Apply(object request, string httpMethod)
        {
            if (!this.IsValid)
            {
                return(RouteResolutionResult.Error(this, this.ErrorMsg));
            }

            if (HttpMethods != null && HttpMethods.Length != 0 && httpMethod != null && !HttpMethods.Contains(httpMethod) && !HttpMethods.Contains("ANY"))
            {
                return(RouteResolutionResult.Error(this, "Allowed HTTP methods '{0}' does not support the specified '{1}' method."
                                                   .Fmt(HttpMethods.Join(", "), httpMethod)));
            }

            var uri = this.Path;

            var unmatchedVariables = new List <string>();

            foreach (var variable in this.variablesMap)
            {
                var property   = variable.Value;
                var value      = property.GetValue(request);
                var isWildCard = variable.Key.EndsWith("*");
                if (value == null && !isWildCard)
                {
                    unmatchedVariables.Add(variable.Key);
                    continue;
                }

                var variableValue = FormatVariable(value);
                uri = uri.Replace(VariablePrefix + variable.Key + VariablePostfix, variableValue);
            }

            if (unmatchedVariables.Any())
            {
                var errMsg = "Could not match following variables: " + string.Join(",", unmatchedVariables.ToArray());
                return(RouteResolutionResult.Error(this, errMsg));
            }

            return(RouteResolutionResult.Success(this, uri));
        }
예제 #3
0
 internal bool HasSameVariables(RouteResolutionResult other)
 {
     return(Route.Variables.All(v => other.Route.Variables.Contains(v)));
 }
예제 #4
0
 internal bool HasSameVariables(RouteResolutionResult other)
 {
     return Route.Variables.All(v => other.Route.Variables.Contains(v));
 }