void BuildOrderedSetOfKeysForRouteValues(ActionDescriptorCollection actions) { Contract.Requires(actions != null); for (var i = 0; i < actions.Items.Count; i++) { var action = actions.Items[i]; if (action.AttributeRouteInfo != null) { continue; } var routeValues = new string[RouteKeys.Length]; for (var j = 0; j < RouteKeys.Length; j++) { action.RouteValues.TryGetValue(RouteKeys[j], out routeValues[j]); } if (!OrdinalIgnoreCaseEntries.TryGetValue(routeValues, out var entries)) { entries = new List <ActionDescriptor>(); OrdinalIgnoreCaseEntries.Add(routeValues, entries); } entries.Add(action); if (!OrdinalEntries.ContainsKey(routeValues)) { OrdinalEntries.Add(routeValues, entries); } } }
public IReadOnlyList <TItem> Select(RouteValueDictionary values) { // Select works based on a string[] of the route values in a pre-calculated order. This code extracts // those values in the correct order. var routeKeys = RouteKeys; var routeValues = new string[routeKeys.Length]; for (var i = 0; i < routeKeys.Length; i++) { values.TryGetValue(routeKeys[i], out var value); routeValues[i] = value as string ?? Convert.ToString(value, CultureInfo.InvariantCulture) ?? string.Empty; } // Now look up, first case-sensitive, then case-insensitive. if (OrdinalEntries.TryGetValue(routeValues, out var matches) || OrdinalIgnoreCaseEntries.TryGetValue(routeValues, out matches)) { Debug.Assert(matches != null); Debug.Assert(matches.Count >= 0); return(matches); } return(Array.Empty <TItem>()); }