private static IList <ControllerActionDescriptor> CreateActionDescriptors(
            ApplicationModel application,
            ControllerModel controller,
            ActionModel action)
        {
            var defaultControllerConstraints      = Enumerable.Empty <IActionConstraintMetadata>();
            var defaultControllerEndpointMetadata = Enumerable.Empty <object>();

            if (controller.Selectors.Count > 0)
            {
                defaultControllerConstraints = controller.Selectors[0].ActionConstraints
                                               .Where(constraint => !(constraint is IRouteTemplateProvider));
                defaultControllerEndpointMetadata = controller.Selectors[0].EndpointMetadata;
            }

            var actionDescriptors = new List <ControllerActionDescriptor>();

            foreach (var result in ActionAttributeRouteModel.GetAttributeRoutes(action))
            {
                var actionSelector     = result.actionSelector;
                var controllerSelector = result.controllerSelector;

                var actionDescriptor = CreateActionDescriptor(action, result.route);
                actionDescriptors.Add(actionDescriptor);
                AddActionFilters(actionDescriptor, action.Filters, controller.Filters, application.Filters);

                var controllerConstraints = defaultControllerConstraints;

                if (controllerSelector?.AttributeRouteModel?.Attribute is IActionConstraintMetadata actionConstraint)
                {
                    // Use the attribute route as a constraint if the controller selector participated in creating this route.
                    controllerConstraints = controllerConstraints.Concat(new[] { actionConstraint });
                }

                AddActionConstraints(actionDescriptor, actionSelector, controllerConstraints);

                // Metadata for the action is more significant so order it before the controller metadata
                var actionDescriptorMetadata = actionSelector.EndpointMetadata.ToList();
                actionDescriptorMetadata.AddRange(defaultControllerEndpointMetadata);

                actionDescriptor.EndpointMetadata = actionDescriptorMetadata;
            }

            return(actionDescriptors);
        }
Exemplo n.º 2
0
        private bool ParameterExistsInAnyRoute(ActionModel action, string parameterName)
        {
            foreach (var selector in ActionAttributeRouteModel.FlattenSelectors(action))
            {
                if (selector.AttributeRouteModel == null)
                {
                    continue;
                }

                var parsedTemplate = TemplateParser.Parse(selector.AttributeRouteModel.Template);
                if (parsedTemplate.GetParameter(parameterName) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
        private bool ParameterExistsInAnyRoute(ActionModel action, string parameterName)
        {
            foreach (var(route, _, _) in ActionAttributeRouteModel.GetAttributeRoutes(action))
            {
                if (route == null)
                {
                    continue;
                }

                var parsedTemplate = TemplateParser.Parse(route.Template);
                if (parsedTemplate.GetParameter(parameterName) != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 4
0
        public static List <TResult> Flatten <TResult>(
            ApplicationModel application,
            Func <ApplicationModel, ControllerModel, ActionModel, SelectorModel, TResult> flattener)
        {
            var results = new List <TResult>();
            var errors  = new Dictionary <MethodInfo, IList <string> >();

            var actionsByMethod    = new Dictionary <MethodInfo, List <(ActionModel, SelectorModel)> >();
            var actionsByRouteName = new Dictionary <string, List <(ActionModel, SelectorModel)> >(StringComparer.OrdinalIgnoreCase);

            var routeTemplateErrors = new List <string>();

            foreach (var controller in application.Controllers)
            {
                foreach (var action in controller.Actions)
                {
                    foreach (var selector in ActionAttributeRouteModel.FlattenSelectors(action))
                    {
                        // PostProcess attribute routes so we can observe any errors.
                        ReplaceAttributeRouteTokens(controller, action, selector, routeTemplateErrors);

                        // Add to the data structures we use to find errors.
                        AddActionToMethodInfoMap(actionsByMethod, action, selector);
                        AddActionToRouteNameMap(actionsByRouteName, action, selector);

                        var result = flattener(application, controller, action, selector);
                        Debug.Assert(result != null);

                        results.Add(result);
                    }
                }
            }

            var attributeRoutingConfigurationErrors = new Dictionary <MethodInfo, string>();

            foreach (var(method, actions) in actionsByMethod)
            {
                ValidateActionGroupConfiguration(
                    method,
                    actions,
                    attributeRoutingConfigurationErrors);
            }

            if (attributeRoutingConfigurationErrors.Count > 0)
            {
                var message = CreateAttributeRoutingAggregateErrorMessage(attributeRoutingConfigurationErrors.Values);

                throw new InvalidOperationException(message);
            }

            var namedRoutedErrors = ValidateNamedAttributeRoutedActions(actionsByRouteName);

            if (namedRoutedErrors.Count > 0)
            {
                var message = CreateAttributeRoutingAggregateErrorMessage(namedRoutedErrors);
                throw new InvalidOperationException(message);
            }

            if (routeTemplateErrors.Count > 0)
            {
                var message = CreateAttributeRoutingAggregateErrorMessage(routeTemplateErrors);
                throw new InvalidOperationException(message);
            }


            return(results);
        }