public void InitializeEndpoints() { foreach (var action in _actions.ActionDescriptors.Items) { if (action.AttributeRouteInfo == null) { // Check each of the conventional templates to see if the action would be reachable // If the action and template are compatible then create an endpoint with the // area/controller/action parameter parts replaced with literals // // e.g. {controller}/{action} with HomeController.Index and HomeController.Login // would result in endpoints: // - Home/Index // - Home/Login foreach (var endpointInfo in ConventionalEndpointInfos) { var actionRouteValues = action.RouteValues; var endpointTemplateSegments = endpointInfo.ParsedTemplate.Segments; if (MatchRouteValue(action, endpointInfo, "Area") && MatchRouteValue(action, endpointInfo, "Controller") && MatchRouteValue(action, endpointInfo, "Action")) { var newEndpointTemplate = TemplateParser.Parse(endpointInfo.Template); for (var i = 0; i < newEndpointTemplate.Segments.Count; i++) { // Check if the template can be shortened because the remaining parameters are optional // // e.g. Matching template {controller=Home}/{action=Index}/{id?} against HomeController.Index // can resolve to the following endpoints: // - /Home/Index/{id?} // - /Home // - / if (UseDefaultValuePlusRemainingSegementsOptional(i, action, endpointInfo, newEndpointTemplate)) { var subTemplate = RouteTemplateWriter.ToString(newEndpointTemplate.Segments.Take(i)); var subEndpoint = CreateEndpoint(action, subTemplate, 0, endpointInfo); _endpoints.Add(subEndpoint); } var segment = newEndpointTemplate.Segments[i]; for (var j = 0; j < segment.Parts.Count; j++) { var part = segment.Parts[j]; if (part.IsParameter && IsMvcParameter(part.Name)) { // Replace parameter with literal value segment.Parts[j] = TemplatePart.CreateLiteral(action.RouteValues[part.Name]); } } } var newTemplate = RouteTemplateWriter.ToString(newEndpointTemplate.Segments); var endpoint = CreateEndpoint(action, newTemplate, 0, endpointInfo); _endpoints.Add(endpoint); } } } else { var endpoint = CreateEndpoint(action, action.AttributeRouteInfo.Template, action.AttributeRouteInfo.Order, action.AttributeRouteInfo); _endpoints.Add(endpoint); } } }
private List <Endpoint> CreateEndpoints() { List <Endpoint> endpoints = new List <Endpoint>(); foreach (var action in _actions.ActionDescriptors.Items) { if (action.AttributeRouteInfo == null) { // In traditional conventional routing setup, the routes defined by a user have a static order // defined by how they are added into the list. We would like to maintain the same order when building // up the endpoints too. // // Start with an order of '1' for conventional routes as attribute routes have a default order of '0'. // This is for scenarios dealing with migrating existing Router based code to Endpoint Routing world. var conventionalRouteOrder = 0; // Check each of the conventional templates to see if the action would be reachable // If the action and template are compatible then create an endpoint with the // area/controller/action parameter parts replaced with literals // // e.g. {controller}/{action} with HomeController.Index and HomeController.Login // would result in endpoints: // - Home/Index // - Home/Login foreach (var endpointInfo in ConventionalEndpointInfos) { var actionRouteValues = action.RouteValues; var endpointTemplateSegments = endpointInfo.ParsedTemplate.Segments; if (MatchRouteValue(action, endpointInfo, "Area") && MatchRouteValue(action, endpointInfo, "Controller") && MatchRouteValue(action, endpointInfo, "Action")) { var newEndpointTemplate = TemplateParser.Parse(endpointInfo.Template); for (var i = 0; i < newEndpointTemplate.Segments.Count; i++) { // Check if the template can be shortened because the remaining parameters are optional // // e.g. Matching template {controller=Home}/{action=Index}/{id?} against HomeController.Index // can resolve to the following endpoints: // - /Home/Index/{id?} // - /Home // - / if (UseDefaultValuePlusRemainingSegementsOptional(i, action, endpointInfo, newEndpointTemplate)) { var subTemplate = RouteTemplateWriter.ToString(newEndpointTemplate.Segments.Take(i)); var subEndpoint = CreateEndpoint( action, endpointInfo.Name, subTemplate, endpointInfo.Defaults, ++conventionalRouteOrder, endpointInfo, suppressLinkGeneration: false); endpoints.Add(subEndpoint); } var segment = newEndpointTemplate.Segments[i]; for (var j = 0; j < segment.Parts.Count; j++) { var part = segment.Parts[j]; if (part.IsParameter && IsMvcParameter(part.Name)) { // Replace parameter with literal value segment.Parts[j] = TemplatePart.CreateLiteral(action.RouteValues[part.Name]); } } } var newTemplate = RouteTemplateWriter.ToString(newEndpointTemplate.Segments); var endpoint = CreateEndpoint( action, endpointInfo.Name, newTemplate, endpointInfo.Defaults, ++conventionalRouteOrder, endpointInfo, suppressLinkGeneration: false); endpoints.Add(endpoint); } } } else { var endpoint = CreateEndpoint( action, action.AttributeRouteInfo.Name, action.AttributeRouteInfo.Template, nonInlineDefaults: null, action.AttributeRouteInfo.Order, action.AttributeRouteInfo, suppressLinkGeneration: action.AttributeRouteInfo.SuppressLinkGeneration); endpoints.Add(endpoint); } } return(endpoints); }