private static void ReplaceAttributeRouteTokens( ControllerActionDescriptor actionDescriptor, IList <string> routeTemplateErrors) { try { actionDescriptor.AttributeRouteInfo.Template = AttributeRouteModel.ReplaceTokens( actionDescriptor.AttributeRouteInfo.Template, actionDescriptor.RouteValues); if (actionDescriptor.AttributeRouteInfo.Name != null) { actionDescriptor.AttributeRouteInfo.Name = AttributeRouteModel.ReplaceTokens( actionDescriptor.AttributeRouteInfo.Name, actionDescriptor.RouteValues); } } catch (InvalidOperationException ex) { // Routing will throw an InvalidOperationException here if we can't parse/replace tokens // in the template. var message = Resources.FormatAttributeRoute_IndividualErrorMessage( actionDescriptor.DisplayName, Environment.NewLine, ex.Message); routeTemplateErrors.Add(message); } }
private static List <RouteInfo> GetRouteInfos(IReadOnlyList <ActionDescriptor> actions) { var routeInfos = new List <RouteInfo>(); var errors = new List <RouteInfo>(); // This keeps a cache of 'Template' objects. It's a fairly common case that multiple actions // will use the same route template string; thus, the `Template` object can be shared. // // For a relatively simple route template, the `Template` object will hold about 500 bytes // of memory, so sharing is worthwhile. var templateCache = new Dictionary <string, RouteTemplate>(StringComparer.OrdinalIgnoreCase); var attributeRoutedActions = actions.Where(a => a.AttributeRouteInfo?.Template != null); foreach (var action in attributeRoutedActions) { var routeInfo = GetRouteInfo(templateCache, action); if (routeInfo.ErrorMessage == null) { routeInfos.Add(routeInfo); } else { errors.Add(routeInfo); } } if (errors.Count > 0) { var allErrors = string.Join( Environment.NewLine + Environment.NewLine, errors.Select( e => Resources.FormatAttributeRoute_IndividualErrorMessage( e.ActionDescriptor.DisplayName, Environment.NewLine, e.ErrorMessage))); var message = Resources.FormatAttributeRoute_AggregateErrorMessage(Environment.NewLine, allErrors); throw new RouteCreationException(message); } return(routeInfos); }