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(); }
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)); }
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); }
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; }
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); }
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"]); }
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"]); }
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); }
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); }