public void ConfigureRoutes(HttpConfiguration config, bool useSchoolYear)
        {
            Preconditions.ThrowIfNull(config, nameof(config));

            string compositeRouteBase = "composites/v{compositeVersion}/" + (useSchoolYear
                                            ? "{schoolYearFromRoute}/"
                                            : string.Empty) + "{organizationCode}/{compositeCategory}/";

            // Construct the route constraint pattern for the composite categories defined.
            var compositeCategoryNames = _compositesMetadataProvider.GetAllCategories()
                                         .Select(x => x.Name)
                                         .ToList();

            // Don't add routes for composites, if none exit.
            if (!compositeCategoryNames.Any())
            {
                return;
            }

            string allCompositeCategoriesConstraintExpression = $@"^(?i)({string.Join("|", compositeCategoryNames)})$";

            // Define default route for all composites
            config.Routes.MapHttpRoute(
                name: "Composites",
                routeTemplate: compositeRouteBase + "{compositeName}/{id}",
                defaults: new
            {
                id = RouteParameter.Optional, controller = "CompositeResource"
            },
                constraints: useSchoolYear
                    ? (object)new
            {
                compositeCategory = allCompositeCategoriesConstraintExpression, schoolYearFromRoute = @"^\d{4}$"
            }
                    : new
            {
                compositeCategory = allCompositeCategoriesConstraintExpression
            }
                );

            var routeMetadataGroupedByCompositeCategory = _compositesMetadataProvider.GetAllRoutes();

            foreach (var routeGrouping in routeMetadataGroupedByCompositeCategory)
            {
                string categoryName = routeGrouping.Key.Name;
                int    routeNumber  = 1;

                foreach (var routeElt in routeGrouping.Value)
                {
                    string relativeRouteTemplate = routeElt.AttributeValue("relativeRouteTemplate")
                                                   .TrimStart('/');

                    config.Routes.MapHttpRoute(
                        name: $"{categoryName}Composites{routeNumber++}",
                        routeTemplate: compositeRouteBase + relativeRouteTemplate,
                        defaults: new
                    {
                        controller = "CompositeResource"
                    },
                        constraints: new
                    {
                        compositeCategory = categoryName
                    });
                }
            }
        }
Example #2
0
        public void Apply(ApplicationModel application)
        {
            var controller =
                application.Controllers.FirstOrDefault(
                    x => x.ControllerType == typeof(CompositeResourceController).GetTypeInfo());

            // composites/v{compositeVersion}/{school year if year specific}/{organizationCode}/{compositeCategoryName (regex constraint}/{compositeName}/{id?}
            // the composite category is constrained by a regex expression
            // the id is optional
            // the attribute on the controller is composites
            if (controller != null)
            {
                var defaultRouteSuffix = new AttributeRouteModel {
                    Template = CreateRouteTemplate() + "{compositeName}/{id?}"
                };

                // the composite controller has only one selector and if more are added this should break

                var selector = controller.Selectors.SingleOrDefault();

                if (selector.AttributeRouteModel != null)
                {
                    // composites have children routes that need to be added to the controller.
                    var routeMetadataGroupedByCompositeCategory = _compositesMetadataProvider.GetAllRoutes();

                    foreach (var routeGrouping in routeMetadataGroupedByCompositeCategory)
                    {
                        foreach (var routeElt in routeGrouping.Value)
                        {
                            string relativeRouteTemplate = routeElt.AttributeValue("relativeRouteTemplate")
                                                           .TrimStart('/');

                            var routeSuffix = new AttributeRouteModel {
                                Template = CreateRouteTemplate() + relativeRouteTemplate
                            };

                            var childSelector = new SelectorModel
                            {
                                AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(
                                    selector.AttributeRouteModel,
                                    routeSuffix)
                            };

                            controller.Selectors.Add(childSelector);
                        }
                    }

                    // set the base selector with the correct route
                    selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(
                        selector.AttributeRouteModel,
                        defaultRouteSuffix);
                }
            }

            string CreateRouteTemplate()
            {
                string template = $"v{ApiVersionConstants.Composite}/";

                if (_apiSettings.GetApiMode() == ApiMode.YearSpecific)
                {
                    template += RouteConstants.SchoolYearFromRoute;
                }

                if (_apiSettings.GetApiMode() == ApiMode.InstanceYearSpecific)
                {
                    template += RouteConstants.InstanceIdFromRoute;
                    template += RouteConstants.SchoolYearFromRoute;
                }

                var compositeCategoryNames = _compositesMetadataProvider
                                             .GetAllCategories()
                                             .Select(x => x.Name)
                                             .ToList <string>();

                string allCompositeCategoriesConstraintExpression = $@"^(?i)({string.Join("|", compositeCategoryNames)})$";

                string categoryName = "{organizationCode}/{compositeCategory}/";

                template += categoryName;

                return(template);
            }
        }