private static RouteValidationResult EnsureCatchAllOnlyAppearAtEnd(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var catchAll = segments.OfType<CatchAllParameterSegment>().ToList(); return catchAll.Count == 1 && segments.Last() != catchAll.Single() ? RouteValidationResult.Failure(string.Format("Catch-all parameters may only appear at the end of a route. Catch all parameter: '{0}'", catchAll.Single().ParameterName)) : RouteValidationResult.Successful(); }
private static RouteValidationResult EnsureNoMoreThanOneCatchAllSegment(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var catchAll = segments.OfType<CatchAllParameterSegment>().ToList(); return catchAll.Count > 1 ? RouteValidationResult.Failure(string.Format("A route cannot have more than one catch-all parameter. Catch all parameters: {0}", string.Join(", ", catchAll.Select(x => "'" + x.ParameterName + "'").ToArray()))) : RouteValidationResult.Successful(); }
private RouteValidationResult EnsureNoUnrecognizableSegments(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var unrecognized = segments.Where(x => SupportedSegmentTypes.Contains(x.GetType()) == false).ToList(); return unrecognized.Count > 0 ? RouteValidationResult.Failure(string.Format("Unrecognized segment types were found. If using a custom segment type, please replace the IRouteValidator to enforce your own route validation rules. Unrecognized types: {0}", string.Join(", ", unrecognized.Select(x => "'" + x.GetType().Name + "'").ToArray()))) : RouteValidationResult.Successful(); }
private static RouteValidationResult MustHaveViewModelSegment(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var hasViewModel = segments.OfType<ParameterSegment>().Any(x => x.ParameterName == "viewModel") || defaults.GetOrDefault<object>("viewModel") != null; return hasViewModel ? RouteValidationResult.Successful() : RouteValidationResult.Failure("The route does not contain a '{viewModel}' segment, and no default ViewModel type was provided."); }
private static RouteValidationResult MustHaveActionSegment(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var hasController = segments.OfType<ParameterSegment>().Any(x => x.ParameterName == "action") || defaults.GetOrDefault<object>("action") != null; return hasController ? RouteValidationResult.Successful() : RouteValidationResult.Failure("The route does not contain an '{action}' segment, and no default action was provided."); }
/// <summary> /// Parses the given route specification, producing a <see cref="ParsedRoute"/>. /// </summary> /// <param name="route">The route.</param> /// <param name="routeSpecification">The route specification.</param> /// <param name="defaults">The defaults.</param> /// <param name="constraints">The constraints.</param> /// <returns></returns> public ParsedRoute Parse(IRoute route, string routeSpecification, RouteValueDictionary defaults, RouteValueDictionary constraints) { var parts = routeSpecification.SplitUrlPath(); var segments = new Segment[parts.Length]; for (var i = 0; i < parts.Length; i++) { var segment = recognisers.Select(x => x.Recognise(parts[i], defaults, constraints)).FirstOrDefault(x => x != null); if (segment == null) { throw new InvalidRouteException( route, string.Format("Invalid route: {0}. The route segment '{1}' was not recognized as a valid segment.", route, parts[i]) ); } segments[i] = segment; } return new ParsedRoute(defaults, constraints, segments); }
private static RouteValidationResult EnsureParameterNamesAreUnique(Segment[] segments, RouteValueDictionary defaults, RouteValueDictionary constraints) { var parameterSegments = segments.OfType<ParameterSegment>().Select(x => x.ParameterName); var catchAllSegments = segments.OfType<CatchAllParameterSegment>().Select(x => x.ParameterName); var parameterNames = parameterSegments.Concat(catchAllSegments).Select(x => x.ToLowerInvariant()); var duplicateNames = parameterNames.GroupBy(x => x).Where(g => g.Count() > 1).Select(x => x.Key).ToList(); return duplicateNames.Count > 0 ? RouteValidationResult.Failure(string.Format("The same parameter name cannot be used twice within a route. The following parameters appeared more than once: {0}", string.Join(", ", duplicateNames.Select(x => "'" + x + "'").ToArray()))) : RouteValidationResult.Successful(); }