// internal for testing internal AttributeRouteEntries GetEntries(ActionDescriptorCollection actions) { var entries = new AttributeRouteEntries(); var routeInfos = GetRouteInfos(_constraintResolver, actions.Items); // We're creating one TreeRouteLinkGenerationEntry per action. This allows us to match the intended // action by expected route values, and then use the TemplateBinder to generate the link. foreach (var routeInfo in routeInfos) { entries.LinkGenerationEntries.Add(new TreeRouteLinkGenerationEntry() { // Using routeInfo.Defaults here WITHOUT adding the RouteGroupKey. We don't want to impact the // behavior of link generation. Binder = new TemplateBinder(_urlEncoder, _contextPool, routeInfo.ParsedTemplate, routeInfo.Defaults), Defaults = routeInfo.Defaults, Constraints = routeInfo.Constraints, Order = routeInfo.Order, GenerationPrecedence = routeInfo.GenerationPrecedence, RequiredLinkValues = routeInfo.ActionDescriptor.RouteValueDefaults, RouteGroup = routeInfo.RouteGroup, Template = routeInfo.ParsedTemplate, Name = routeInfo.Name, }); } // We're creating one AttributeRouteMatchingEntry per group, so we need to identify the distinct set of // groups. It's guaranteed that all members of the group have the same template and precedence, // so we only need to hang on to a single instance of the RouteInfo for each group. var distinctRouteInfosByGroup = GroupRouteInfosByGroupId(routeInfos); foreach (var routeInfo in distinctRouteInfosByGroup) { // Note that because we only support 'inline' defaults, each routeInfo group also has the same // set of defaults. // // We then inject the route group as a default for the matcher so it gets passed back to MVC // for use in action selection. var defaults = new RouteValueDictionary(routeInfo.Defaults); defaults[TreeRouter.RouteGroupKey] = routeInfo.RouteGroup; entries.MatchingEntries.Add(new TreeRouteMatchingEntry() { Order = routeInfo.Order, Precedence = routeInfo.MatchPrecedence, Target = _target, RouteName = routeInfo.Name, RouteTemplate = routeInfo.ParsedTemplate, TemplateMatcher = new TemplateMatcher(routeInfo.ParsedTemplate, defaults), Constraints = routeInfo.Constraints, }); } return(entries); }
private TreeRouter BuildRoute(AttributeRouteEntries entries, int version) { var routeBuilder = new TreeRouteBuilder(_target, _loggerFactory); foreach (var entry in entries.LinkGenerationEntries) { routeBuilder.Add(entry); } foreach (var entry in entries.MatchingEntries) { routeBuilder.Add(entry); } return(routeBuilder.Build(version)); }