internal List <RouteEntry> MapMvcAttributeRoutes(ReflectedAsyncControllerDescriptor controllerDescriptor) { RoutePrefixAttribute prefixAttribute = GetPrefixFrom(controllerDescriptor); ValidatePrefixTemplate(prefixAttribute, controllerDescriptor); RouteAreaAttribute area = GetAreaFrom(controllerDescriptor); string areaName = GetAreaName(controllerDescriptor, area); string areaPrefix = area != null ? area.AreaPrefix ?? area.AreaName : null; ValidateAreaPrefixTemplate(areaPrefix, areaName, controllerDescriptor); string controllerName = controllerDescriptor.ControllerName; AsyncActionMethodSelector actionSelector = controllerDescriptor.Selector; IEnumerable <MethodInfo> actionMethodsInfo = actionSelector.AliasedMethods .Concat(actionSelector.NonAliasedMethods.SelectMany(x => x)) .Where(m => m.DeclaringType == controllerDescriptor.ControllerType); if (actionSelector.AllowLegacyAsyncActions) { // if the ActionAsync / ActionCompleted pattern is used, we need to remove the "Completed" methods // and not look up routing attributes on them actionMethodsInfo = actionMethodsInfo.Where(m => !m.Name.EndsWith("Completed", StringComparison.OrdinalIgnoreCase)); } List <RouteEntry> routeEntries = new List <RouteEntry>(); foreach (var method in actionMethodsInfo) { string actionName = GetCanonicalActionName(method, actionSelector.AllowLegacyAsyncActions); IEnumerable <IDirectRouteInfoProvider> routeAttributes = GetRouteAttributes(method); foreach (var routeAttribute in routeAttributes) { ValidateTemplate(routeAttribute, actionName, controllerDescriptor); string prefix = prefixAttribute != null ? prefixAttribute.Prefix : null; string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.RouteTemplate); Route route = _routeBuilder.BuildDirectRoute(template, routeAttribute.Verbs, controllerName, actionName, method, areaName); RouteEntry entry = new RouteEntry { Name = routeAttribute.RouteName ?? template, Route = route, RouteTemplate = template, ParsedRoute = RouteParser.Parse(route.Url), Order = routeAttribute.RouteOrder }; routeEntries.Add(entry); } } return(routeEntries); }
/// <summary> /// Builds an <see cref="Route"/> for a particular controller. /// </summary> /// <param name="routeTemplate">The tokenized route template for the route.</param> /// <param name="routeInfoProvider">The info provider for the route.</param> /// <param name="controllerDescriptor">The controller the route attribute has been applied on.</param> /// <param name="actionDescriptors">The actions reachable by this route.</param> /// <param name="routeIsForAction">Whether or not the direct route is for an action.</param> /// <returns>The generated <see cref="Route"/>.</returns> public Route BuildDirectRoute( string routeTemplate, IRouteInfoProvider routeInfoProvider, ControllerDescriptor controllerDescriptor, IEnumerable <ActionDescriptor> actionDescriptors, bool routeIsForAction) { if (routeTemplate == null) { throw Error.ArgumentNull("routeTemplate"); } if (routeInfoProvider == null) { throw Error.ArgumentNull("routeInfoProvider"); } if (controllerDescriptor == null) { throw Error.ArgumentNull("controllerDescriptor"); } if (actionDescriptors == null || !actionDescriptors.Any()) { throw Error.ParameterCannotBeNullOrEmpty("actionDescriptors"); } string controllerName = controllerDescriptor.ControllerName; RouteAreaAttribute area = controllerDescriptor.GetAreaFrom(); string areaName = controllerDescriptor.GetAreaName(area); RouteValueDictionary defaults = new RouteValueDictionary { { "controller", controllerName } }; if (routeIsForAction) { ActionDescriptor actionDescriptor = actionDescriptors.Single(); defaults.Add("action", actionDescriptor.ActionName); } RouteValueDictionary constraints = new RouteValueDictionary(); string detokenizedRouteTemplate = InlineRouteTemplateParser.ParseRouteTemplate(routeTemplate, defaults, constraints, ConstraintResolver); ParsedRoute parsedRoute = RouteParser.Parse(detokenizedRouteTemplate); RouteValueDictionary dataTokens = new RouteValueDictionary(); dataTokens[RouteDataTokenKeys.DirectRoutePrecedence] = RoutePrecedence.Compute(parsedRoute, constraints); dataTokens[RouteDataTokenKeys.DirectRouteController] = controllerDescriptor; dataTokens[RouteDataTokenKeys.DirectRouteActions] = actionDescriptors; int order = 0; IOrderedRouteInfoProvider orderedAttribute = routeInfoProvider as IOrderedRouteInfoProvider; if (orderedAttribute != null) { order = orderedAttribute.Order; } dataTokens[RouteDataTokenKeys.DirectRouteOrder] = order; if (areaName != null) { dataTokens.Add(RouteDataTokenKeys.Area, areaName); dataTokens.Add(RouteDataTokenKeys.UseNamespaceFallback, value: false); Type controllerType = controllerDescriptor.ControllerType; if (controllerType != null) { dataTokens.Add(RouteDataTokenKeys.Namespaces, new[] { controllerType.Namespace }); } } Route route = new Route(detokenizedRouteTemplate, new MvcRouteHandler()) { Defaults = defaults, Constraints = constraints, DataTokens = dataTokens }; return(route); }
internal List <RouteEntry> MapMvcAttributeRoutes(ReflectedAsyncControllerDescriptor controllerDescriptor) { string prefix = controllerDescriptor.GetPrefixFrom(); ValidatePrefixTemplate(prefix, controllerDescriptor); RouteAreaAttribute area = controllerDescriptor.GetAreaFrom(); string areaName = controllerDescriptor.GetAreaName(area); string areaPrefix = area != null ? area.AreaPrefix ?? area.AreaName : null; ValidateAreaPrefixTemplate(areaPrefix, areaName, controllerDescriptor); string controllerName = controllerDescriptor.ControllerName; AsyncActionMethodSelector actionSelector = controllerDescriptor.Selector; IEnumerable <MethodInfo> actionMethodsInfo = actionSelector.DirectRouteMethods; List <RouteEntry> routeEntries = new List <RouteEntry>(); foreach (var method in actionMethodsInfo) { string actionName = actionSelector.GetActionName(method); IEnumerable <IRouteInfoProvider> routeAttributes = GetRouteAttributes(method, controllerDescriptor.ControllerType); IEnumerable <string> verbs = GetActionVerbs(method); foreach (var routeAttribute in routeAttributes) { ValidateTemplate(routeAttribute.Template, actionName, controllerDescriptor); string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.Template); Route route = _routeBuilder.BuildDirectRoute(template, verbs, controllerName, actionName, method, areaName); RouteEntry entry = new RouteEntry { Name = routeAttribute.Name, Route = route, Template = template, ParsedRoute = RouteParser.Parse(route.Url), HasVerbs = verbs.Any() }; routeEntries.Add(entry); } } // Check for controller-level routes. IEnumerable <IRouteInfoProvider> controllerRouteAttributes = controllerDescriptor.GetDirectRoutes(); foreach (var routeAttribute in controllerRouteAttributes) { string template = CombinePrefixAndAreaWithTemplate(areaPrefix, prefix, routeAttribute.Template); Route route = _routeBuilder.BuildDirectRoute(template, controllerDescriptor); RouteEntry entry = new RouteEntry { Name = routeAttribute.Name, Route = route, Template = template, ParsedRoute = RouteParser.Parse(route.Url) }; routeEntries.Add(entry); } return(routeEntries); }