예제 #1
0
        public void Combine_NullOrNullTemplateReflectedAttributeRouteModels(
            AttributeRouteModel left,
            AttributeRouteModel right)
        {
            // Arrange & Act
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.Null(combined);
        }
예제 #2
0
        public void Combine_Names(
            AttributeRouteModel left,
            AttributeRouteModel right,
            string expectedName)
        {
            // Arrange & Act
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.NotNull(combined);
            Assert.Equal(expectedName, combined.Name);
        }
예제 #3
0
        public void Combine_ValidReflectedAttributeRouteModels(
            AttributeRouteModel left,
            AttributeRouteModel right,
            AttributeRouteModel expectedResult)
        {
            // Arrange & Act
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.NotNull(combined);
            Assert.Equal(expectedResult.Template, combined.Template);
        }
예제 #4
0
        public void Combine_Orders(
            AttributeRouteModel left,
            AttributeRouteModel right,
            int?expected)
        {
            // Arrange & Act
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.NotNull(combined);
            Assert.Equal(expected, combined.Order);
        }
예제 #5
0
        public void Combine_SetsSuppressPathGenerationToFalse_IfNeitherIsTrue()
        {
            // Arrange
            var left = new AttributeRouteModel
            {
                Template = "Template",
            };
            var right    = new AttributeRouteModel();
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.False(combined.SuppressPathMatching);
        }
예제 #6
0
        public void Combine_RightOverridesReflectedAttributeRouteModel(
            AttributeRouteModel left,
            AttributeRouteModel right)
        {
            // Arrange
            var expectedTemplate = AttributeRouteModel.CombineTemplates(null, right.Template);

            // Act
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.NotNull(combined);
            Assert.Equal(expectedTemplate, combined.Template);
            Assert.Equal(combined.Order, right.Order);
        }
예제 #7
0
        public static IEnumerable <(AttributeRouteModel?route, SelectorModel actionSelector, SelectorModel?controllerSelector)> GetAttributeRoutes(ActionModel actionModel)
        {
            var controllerAttributeRoutes = actionModel.Controller.Selectors
                                            .Where(sm => sm.AttributeRouteModel != null)
                                            .Select(sm => sm.AttributeRouteModel)
                                            .ToList();

            foreach (var actionSelectorModel in actionModel.Selectors)
            {
                var actionRouteModel = actionSelectorModel.AttributeRouteModel;

                // We check the action to see if the template allows combination behavior
                // (It doesn't start with / or ~/) so that in the case where we have multiple
                // [Route] attributes on the controller we don't end up creating multiple
                if (actionRouteModel != null && actionRouteModel.IsAbsoluteTemplate)
                {
                    var route = AttributeRouteModel.CombineAttributeRouteModel(
                        left: null,
                        right: actionRouteModel);

                    yield return(route, actionSelectorModel, null);
                }
                else if (controllerAttributeRoutes.Count > 0)
                {
                    for (var i = 0; i < actionModel.Controller.Selectors.Count; i++)
                    {
                        // We're using the attribute routes from the controller
                        var controllerSelector = actionModel.Controller.Selectors[i];

                        var route = AttributeRouteModel.CombineAttributeRouteModel(
                            controllerSelector.AttributeRouteModel,
                            actionRouteModel);

                        yield return(route, actionSelectorModel, controllerSelector);
                    }
                }

                else
                {
                    var route = AttributeRouteModel.CombineAttributeRouteModel(
                        left: null,
                        right: actionRouteModel);

                    yield return(route, actionSelectorModel, null);
                }
            }
        }
예제 #8
0
        public void Combine_SetsSuppressPathGenerationToTrue_IfEitherIsTrue(bool leftSuppress, bool rightSuppress)
        {
            // Arrange
            var left = new AttributeRouteModel
            {
                Template             = "Template",
                SuppressPathMatching = leftSuppress,
            };
            var right = new AttributeRouteModel
            {
                SuppressPathMatching = rightSuppress,
            };
            var combined = AttributeRouteModel.CombineAttributeRouteModel(left, right);

            // Assert
            Assert.True(combined.SuppressPathMatching);
        }
예제 #9
0
        public static IEnumerable <SelectorModel> FlattenSelectors(ActionModel actionModel)
        {
            // Loop through all attribute routes defined on the controller.
            // These perform a cross-product with all of the action-level attribute routes.
            var controllerSelectors = actionModel.Controller.Selectors
                                      .Where(sm => sm.AttributeRouteModel != null)
                                      .ToList();

            // We also include metadata and action constraints from the controller
            // even when there are no routes, or when an action overrides the route template.
            SelectorModel?additionalSelector = null;

            if (actionModel.Controller.Selectors.Count > 0)
            {
                // This logic seems arbitrary but there's a good reason for it.
                //
                // When we build the controller level selectors, any metadata or action constraints
                // that aren't IRouteTemplateProvider will be included in all selectors. So we
                // pick any selector and then grab all of the stuff that isn't IRouteTemplateProvider
                // then we've found all of the items that aren't routes.
                //
                // This is fragile wrt application model customizing the data - but no one has
                // run into an issue with this and its pretty esoteric.
                additionalSelector = new SelectorModel(actionModel.Controller.Selectors.First());
                additionalSelector.AttributeRouteModel = null;

                for (var i = additionalSelector.ActionConstraints.Count - 1; i >= 0; i--)
                {
                    if (additionalSelector.ActionConstraints[i] is IRouteTemplateProvider)
                    {
                        additionalSelector.ActionConstraints.RemoveAt(i);
                    }
                }

                for (var i = additionalSelector.EndpointMetadata.Count - 1; i >= 0; i--)
                {
                    if (additionalSelector.EndpointMetadata[i] is IRouteTemplateProvider)
                    {
                        additionalSelector.EndpointMetadata.RemoveAt(i);
                    }
                }
            }

            var actionConstraints = new List <IActionConstraintMetadata>();

            foreach (var actionSelector in actionModel.Selectors)
            {
                var actionRouteModel = actionSelector.AttributeRouteModel;

                // We check the action to see if the template allows combination behavior
                // (It doesn't start with / or ~/) so that in the case where we have multiple
                // [Route] attributes on the controller we don't end up creating multiple
                if (actionRouteModel != null && actionRouteModel.IsAbsoluteTemplate)
                {
                    // We're overriding the routes from the controller, but any *unbound* constraints
                    // still apply.
                    var selector = new SelectorModel(actionSelector);

                    selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(
                        left: null,
                        right: actionRouteModel);

                    AddActionConstraints(selector, additionalSelector?.ActionConstraints);
                    AddEndpointMetadata(selector, additionalSelector?.EndpointMetadata);

                    yield return(selector);
                }
                else if (controllerSelectors.Count > 0)
                {
                    for (var i = 0; i < controllerSelectors.Count; i++)
                    {
                        var controllerSelector = controllerSelectors[i];

                        // We're using the attribute routes from the controller
                        var selector = new SelectorModel(actionSelector);

                        selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(
                            controllerSelector.AttributeRouteModel,
                            actionRouteModel);

                        AddActionConstraints(selector, controllerSelector.ActionConstraints);
                        AddEndpointMetadata(selector, controllerSelector.EndpointMetadata);

                        // No need to include the additional selector here because it would duplicate
                        // data in controllerSelector.

                        yield return(selector);
                    }
                }
                else
                {
                    // There are no routes on the controller, but any *unbound* constraints
                    // still apply.
                    var selector = new SelectorModel(actionSelector);

                    selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(
                        left: null,
                        right: actionRouteModel);

                    AddActionConstraints(selector, additionalSelector?.ActionConstraints);
                    AddEndpointMetadata(selector, additionalSelector?.EndpointMetadata);

                    yield return(selector);
                }
            }
        }