Example #1
0
        public void GetVirtualPathWithNonParameterConstraintReturnsUrlWithoutQueryString()
        {
            // Arrange
            var context = CreateVirtualPathContext(new { p1 = "hello", p2 = "1234" });

            var target = new Mock <IRouteConstraint>();

            target.Setup(e => e.Match(It.IsAny <HttpContext>(),
                                      It.IsAny <IRouter>(),
                                      It.IsAny <string>(),
                                      It.IsAny <IDictionary <string, object> >(),
                                      It.IsAny <RouteDirection>()))
            .Returns(true)
            .Verifiable();

            TemplateRoute r = CreateRoute(
                "{p1}/{p2}",
                new { p2 = "catchall" },
                true,
                new RouteValueDictionary(new { p2 = target.Object }));

            // Act
            var virtualPath = r.GetVirtualPath(context);

            // Assert
            Assert.True(context.IsBound);
            Assert.NotNull(virtualPath);
            Assert.Equal("hello/1234", virtualPath);

            target.VerifyAll();
        }
Example #2
0
        public void Publish(IEnumerable<RouteDescriptor> routes, RequestDelegate pipeline)
        {
            var orderedRoutes = routes
                .OrderByDescending(r => r.Priority)
                .ToList();

            string routePrefix = "";
            if (!String.IsNullOrWhiteSpace(_shellSettings.RequestUrlPrefix))
            {
                routePrefix = _shellSettings.RequestUrlPrefix + "/";
            }

            orderedRoutes.Insert(0, new RouteDescriptor
            {
                Route = new Route("Default", "{area}/{controller}/{action}/{id?}")
            });


            var inlineConstraint = _routeBuilder.ServiceProvider.GetService<IInlineConstraintResolver>();

            foreach (var route in orderedRoutes)
            {
                IRouter router = new TemplateRoute(
                    _routeBuilder.DefaultHandler,
                    route.Route.RouteName,
                    routePrefix + route.Route.RouteTemplate,
                    route.Route.Defaults,
                    route.Route.Constraints,
                    route.Route.DataTokens,
                    inlineConstraint);

                _routeBuilder.Routes.Add(new TenantRoute(_shellSettings, router, pipeline));
            }
        }
        public SubdomainTemplateRoute(IRouter target, string routeName, string subdomainTemplate, string routeTemplate, IDictionary<string, object> defaults, IDictionary<string, object> constraints, IDictionary<string, object> dataTokens, IInlineConstraintResolver inlineConstraintResolver) {
            _innerRoute = new TemplateRoute(target, routeName, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver);
            _subdomainTemplate = subdomainTemplate;
            _target = target;

            _matcher = new TemplateMatcher(TemplateParser.Parse(subdomainTemplate), Defaults);

            Name = routeName;
        }
		/// <summary>
		/// Gets useful information from the specified template route
		/// </summary>
		/// <param name="route">Template route to get information from</param>
		/// <returns>Information from the route</returns>
		private RouteInfo ProcessTemplateRoute(TemplateRoute route)
		{
			var info = new RouteInfo
			{
				Constraints = _constraintsProcessor.ProcessConstraints(route.Constraints),
				Defaults = route.Defaults.ToDictionary(x => x.Key.ToLowerInvariant(), x => x.Value),
				Optional = new List<string>(),
			};
			var template = TemplateParser.Parse(route.RouteTemplate);
			_parser.Parse(template, info);

			return info;
		}
        public void Publish(IEnumerable<RouteDescriptor> routes, RequestDelegate pipeline)
        {
            // Register one top level TenantRoute per tenant. Each instance contains all the routes
            // for this tenant.

            // In the case of several tenants, they will all be checked by ShellSettings. To optimize 
            // the TenantRoute resolution we can create a single Router type that would index the
            // TenantRoute object by their ShellSetting. This way there would just be one lookup.
            // And the ShellSettings test in TenantRoute would also be useless.

            var orderedRoutes = routes
                .OrderByDescending(r => r.Priority)
                .ToList();

            string routePrefix = "";
            if (!String.IsNullOrWhiteSpace(_shellSettings.RequestUrlPrefix))
            {
                routePrefix = _shellSettings.RequestUrlPrefix + "/";
            }

            // The default route is added to each tenant as a template route, with a prefix
            orderedRoutes.Add(new RouteDescriptor
            {
                Route = new Route("Default", "{area:exists}/{controller}/{action}/{id?}")
            });

            var inlineConstraint = _routeBuilder.ServiceProvider.GetService<IInlineConstraintResolver>();

            var templateRoutes = new List<IRouter>();

            foreach (var route in orderedRoutes)
            {
                IRouter router = new TemplateRoute(
                    _routeBuilder.DefaultHandler,
                    route.Route.RouteName,
                    routePrefix + route.Route.RouteTemplate,
                    route.Route.Defaults,
                    route.Route.Constraints,
                    route.Route.DataTokens,
                    inlineConstraint);

                templateRoutes.Add(router);
            }

            _routeBuilder.Routes.Add(new TenantRoute(_shellSettings, templateRoutes, pipeline));
        }
Example #6
0
        public void RouteWithCatchAllRejectsConstraints()
        {
            // Arrange
            var context = CreateVirtualPathContext(new { p1 = "abcd" });

            TemplateRoute r = CreateRoute(
                "{p1}/{*p2}",
                new { p2 = "catchall" },
                true,
                new RouteValueDictionary(new { p2 = "\\d{4}" }));

            // Act
            var virtualPath = r.GetVirtualPath(context);

            // Assert
            Assert.False(context.IsBound);
            Assert.Null(virtualPath);
        }
Example #7
0
        public void RouteGenerationAcceptsConstraints()
        {
            // Arrange
            var context = CreateVirtualPathContext(new { p1 = "hello", p2 = "1234" });

            TemplateRoute r = CreateRoute(
                "{p1}/{p2}",
                new { p2 = "catchall" },
                true,
                new RouteValueDictionary(new { p2 = "\\d{4}" }));

            // Act
            var virtualPath = r.GetVirtualPath(context);

            // Assert
            Assert.True(context.IsBound);
            Assert.NotNull(virtualPath);
            Assert.Equal("hello/1234", virtualPath);
        }
        public void Publish(IEnumerable<RouteDescriptor> routes, RequestDelegate pipeline) {
            var routesArray = routes
                .OrderByDescending(r => r.Priority)
                .ToArray();

            foreach (var route in routesArray) {
                
                IRouter router = new TemplateRoute(
                    _routeBuilder.DefaultHandler,
                    route.Route.RouteName,
                    route.Route.RouteTemplate,
                    route.Route.Defaults,
                    route.Route.Constraints,
                    route.Route.DataTokens,
                    _routeBuilder.ServiceProvider.GetService<IInlineConstraintResolver>());

                _routeBuilder.AddTenantRoute(_shellSettings.RequestUrlPrefix, router, pipeline);

            }
        }
        public static IRouteBuilder MapLocaleRoute(
            this IRouteBuilder routeBuilder,
            string locale,
            string routeTemplate,
            object defaults)
        {
            var defaultsDictionary = new RouteValueDictionary(defaults);
            defaultsDictionary.Add("locale", locale);

            var constraintResolver = routeBuilder.ServiceProvider.GetService<IInlineConstraintResolver>();

            var route = new TemplateRoute(
                target: routeBuilder.DefaultHandler,
                routeTemplate: routeTemplate,
                defaults: defaultsDictionary,
                constraints: null,
                dataTokens: null,
                inlineConstraintResolver: constraintResolver);
            routeBuilder.Routes.Add(route);

            return routeBuilder;
        }
Example #10
0
        public async Task RouteAsync_InlineConstraint_OptionalParameter_ConstraintFails()
        {
            // Arrange
            var template = "{controller}/{action}/{id:range(1,20)?}";

            var context = CreateRouteContext("/Home/Index/100");

            IDictionary<string, object> routeValues = null;
            var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
            mockTarget
                .Setup(s => s.RouteAsync(It.IsAny<RouteContext>()))
                .Callback<RouteContext>(ctx =>
                {
                    routeValues = ctx.RouteData.Values;
                    ctx.IsHandled = true;
                })
                .Returns(Task.FromResult(true));

            var route = new TemplateRoute(
                mockTarget.Object,
                template,
                defaults: null,
                constraints: null,
                dataTokens: null,
                inlineConstraintResolver: _inlineConstraintResolver);

            Assert.NotEmpty(route.Constraints);
            Assert.IsType<OptionalRouteConstraint>(route.Constraints["id"]);

            // Act
            await route.RouteAsync(context);

            // Assert
            Assert.False(context.IsHandled);
        }
Example #11
0
        public async Task RouteAsync_InlineConstraint_OptionalParameter_WithInConstructorConstraint()
        {
            // Arrange
            var template = "{controller}/{action}/{id:int?}";

            var context = CreateRouteContext("/Home/Index/5");

            IDictionary<string, object> routeValues = null;
            var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
            mockTarget
                .Setup(s => s.RouteAsync(It.IsAny<RouteContext>()))
                .Callback<RouteContext>(ctx =>
                {
                    routeValues = ctx.RouteData.Values;
                    ctx.IsHandled = true;
                })
                .Returns(Task.FromResult(true));

            var constraints = new Dictionary<string, object>();
            constraints.Add("id", new RangeRouteConstraint(1, 20));

            var route = new TemplateRoute(
                mockTarget.Object,
                template,
                defaults: null,
                constraints: constraints,
                dataTokens: null,
                inlineConstraintResolver: _inlineConstraintResolver);

            Assert.NotEmpty(route.Constraints);
            Assert.IsType<OptionalRouteConstraint>(route.Constraints["id"]);
            var innerConstraint = ((OptionalRouteConstraint)route.Constraints["id"]).InnerConstraint;
            Assert.IsType<CompositeRouteConstraint>(innerConstraint);
            var compositeConstraint = (CompositeRouteConstraint)innerConstraint;
            Assert.Equal(compositeConstraint.Constraints.Count<IRouteConstraint>(), 2);

            Assert.Single(compositeConstraint.Constraints, c => c is IntRouteConstraint);
            Assert.Single(compositeConstraint.Constraints, c => c is RangeRouteConstraint);

            // Act
            await route.RouteAsync(context);

            // Assert
            Assert.True(context.IsHandled);
            Assert.True(routeValues.ContainsKey("id"));
            Assert.Equal("5", routeValues["id"]);

            Assert.True(context.RouteData.Values.ContainsKey("id"));
            Assert.Equal("5", context.RouteData.Values["id"]);
        }
Example #12
0
        public async Task RouteAsync_InlineConstraint_Regex()
        {
            // Arrange
            var template = @"{controller}/{action}/{ssn:regex(^\d{{3}}-\d{{3}}-\d{{4}}$)}";

            var context = CreateRouteContext("/Home/Index/123-456-7890");

            IDictionary<string, object> routeValues = null;
            var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
            mockTarget
                .Setup(s => s.RouteAsync(It.IsAny<RouteContext>()))
                .Callback<RouteContext>(ctx =>
                {
                    routeValues = ctx.RouteData.Values;
                    ctx.IsHandled = true;
                })
                .Returns(Task.FromResult(true));

            var route = new TemplateRoute(
                mockTarget.Object,
                template,
                defaults: null,
                constraints: null,
                dataTokens: null,
                inlineConstraintResolver: _inlineConstraintResolver);

            Assert.NotEmpty(route.Constraints);
            Assert.IsType<RegexInlineRouteConstraint>(route.Constraints["ssn"]);

            // Act
            await route.RouteAsync(context);

            // Assert
            Assert.True(context.IsHandled);
            Assert.True(routeValues.ContainsKey("ssn"));
            Assert.Equal("123-456-7890", routeValues["ssn"]);

            Assert.True(context.RouteData.Values.ContainsKey("ssn"));
            Assert.Equal("123-456-7890", context.RouteData.Values["ssn"]);
        }
Example #13
0
        public async Task RouteAsync_CleansUpMergedRouteData_IfConstraintThrows()
        {
            // Arrange
            var template = "{controller}/{action}/{id:int}";

            var context = CreateRouteContext("/Home/Index/5");
            var originalRouteDataValues = context.RouteData.Values;
            originalRouteDataValues.Add("country", "USA");

            var originalDataTokens = context.RouteData.DataTokens;
            originalDataTokens.Add("company", "Contoso");

            var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
            mockTarget
                .Setup(s => s.RouteAsync(It.IsAny<RouteContext>()))
                .Callback<RouteContext>(ctx =>
                {
                    ctx.IsHandled = true;
                })
                .Returns(Task.FromResult(true));

            var constraint = new Mock<IRouteConstraint>(MockBehavior.Strict);
            constraint
                .Setup(c => c.Match(
                    It.IsAny<HttpContext>(),
                    It.IsAny<IRouter>(),
                    It.IsAny<string>(),
                    It.IsAny<IDictionary<string, object>>(),
                    It.IsAny<RouteDirection>()))
                .Callback(() => { throw new Exception(); });

            var route = new TemplateRoute(
                mockTarget.Object,
                template,
                defaults: null,
                constraints: new RouteValueDictionary(new { action = constraint.Object }),
                dataTokens: new RouteValueDictionary(new { today = "Friday" }),
                inlineConstraintResolver: _inlineConstraintResolver);

            // Act
            var ex = await Assert.ThrowsAsync<Exception>(() => route.RouteAsync(context));

            // Assert
            Assert.True(context.RouteData.Values.ContainsKey("country"));
            Assert.Equal("USA", context.RouteData.Values["country"]);
            Assert.False(context.RouteData.Values.ContainsKey("id"));
            Assert.Same(originalRouteDataValues, context.RouteData.Values);

            Assert.Equal("Contoso", context.RouteData.DataTokens["company"]);
            Assert.False(context.RouteData.DataTokens.ContainsKey("today"));
            Assert.Same(originalDataTokens, context.RouteData.DataTokens);
        }
Example #14
0
        public async Task RouteAsync_CleansUpMergedRouteData_IfRouteDoesNotMatch()
        {
            // Arrange
            var template = "{controller}/{action}/{id:int}";

            var context = CreateRouteContext("/Home/Index/5");
            var originalRouteDataValues = context.RouteData.Values;
            originalRouteDataValues.Add("country", "USA");

            var originalDataTokens = context.RouteData.DataTokens;
            originalDataTokens.Add("company", "Contoso");

            IDictionary<string, object> routeValues = null;
            var mockTarget = new Mock<IRouter>(MockBehavior.Strict);
            mockTarget
                .Setup(s => s.RouteAsync(It.IsAny<RouteContext>()))
                .Callback<RouteContext>(ctx =>
                {
                    routeValues = ctx.RouteData.Values;
                    ctx.IsHandled = false;
                })
                .Returns(Task.FromResult(true));

            var route = new TemplateRoute(
                mockTarget.Object,
                template,
                defaults: null,
                constraints: null,
                dataTokens: new RouteValueDictionary(new { today = "Friday" }),
                inlineConstraintResolver: _inlineConstraintResolver);

            // Act
            await route.RouteAsync(context);

            // Assert
            Assert.NotNull(routeValues);

            Assert.True(routeValues.ContainsKey("country"));
            Assert.Equal("USA", routeValues["country"]);
            Assert.True(routeValues.ContainsKey("id"));
            Assert.Equal("5", routeValues["id"]);

            Assert.True(context.RouteData.Values.ContainsKey("country"));
            Assert.Equal("USA", context.RouteData.Values["country"]);
            Assert.False(context.RouteData.Values.ContainsKey("id"));
            Assert.Same(originalRouteDataValues, context.RouteData.Values);

            Assert.Equal("Contoso", context.RouteData.DataTokens["company"]);
            Assert.False(context.RouteData.DataTokens.ContainsKey("today"));
            Assert.Same(originalDataTokens, context.RouteData.DataTokens);
        }