public void GetPathByRouteValues_ParameterMatchesRequireValues_NoAmbientValues(string[] routeNames, string[] routeValues, string expectedPath)
        {
            // Arrange
            var homeIndex = EndpointFactory.CreateRouteEndpoint(
                "{controller}/{action}/{id?}",
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
            var homeLogin = EndpointFactory.CreateRouteEndpoint(
                "{controller}/{action}/{id?}",
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Login", })) });

            var linkGenerator = CreateLinkGenerator(homeIndex, homeLogin);

            var context     = new EndpointSelectorContext();
            var httpContext = CreateHttpContext();

            httpContext.Features.Set <IRouteValuesFeature>(context);

            var values = new RouteValueDictionary();

            for (int i = 0; i < routeNames.Length; i++)
            {
                values[routeNames[i]] = routeValues[i];
            }

            // Act
            var generatedPath = linkGenerator.GetPathByRouteValues(
                httpContext,
                routeName: null,
                values: values);

            // Assert
            Assert.Equal(expectedPath, generatedPath);
        }
Example #2
0
        public Task Invoke(HttpContext httpContext)
        {
            var feature = new EndpointSelectorContext(httpContext);

            // There's already an endpoint, skip maching completely
            if (feature.Endpoint != null)
            {
                Log.MatchSkipped(_logger, feature.Endpoint);
                return(_next(httpContext));
            }

            // There's an inherent race condition between waiting for init and accessing the matcher
            // this is OK because once `_matcher` is initialized, it will not be set to null again.
            var matcherTask = InitializeAsync();

            if (!matcherTask.IsCompletedSuccessfully)
            {
                return(AwaitMatcher(this, httpContext, feature, matcherTask));
            }

            var matchTask = matcherTask.Result.MatchAsync(httpContext, feature);

            if (!matchTask.IsCompletedSuccessfully)
            {
                return(AwaitMatch(this, httpContext, feature, matchTask));
            }

            return(SetRoutingAndContinue(httpContext, feature));
Example #3
0
        public void GetPathByName_WithHttpContext_DoesNotUseAmbientValues()
        {
            // Arrange
            var endpoint1 = EndpointFactory.CreateRouteEndpoint("some-endpoint/{p}", metadata: new[] { new EndpointNameMetadata("name1"), });
            var endpoint2 = EndpointFactory.CreateRouteEndpoint("some#-other-endpoint/{p}", metadata: new[] { new EndpointNameMetadata("name2"), });

            var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);

            var context = new EndpointSelectorContext()
            {
                RouteValues = new RouteValueDictionary(new { p = "5", })
            };
            var httpContext = CreateHttpContext();

            httpContext.Features.Set <IRouteValuesFeature>(context);
            httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");

            var values = new { query = "some?query", };

            // Act
            var path = linkGenerator.GetPathByName(
                httpContext,
                endpointName: "name2",
                values,
                fragment: new FragmentString("#Fragment?"),
                options: new LinkOptions()
            {
                AppendTrailingSlash = true,
            });

            // Assert
            Assert.Null(path);
        }
Example #4
0
        public async Task Invoke(HttpContext httpContext)
        {
            var feature = new EndpointSelectorContext();

            // There's an inherent race condition between waiting for init and accessing the matcher
            // this is OK because once `_matcher` is initialized, it will not be set to null again.
            var matcher = await InitializeAsync();

            await matcher.MatchAsync(httpContext, feature);

            if (feature.Endpoint != null)
            {
                // Set the endpoint feature only on success. This means we won't overwrite any
                // existing state for related features unless we did something.
                SetFeatures(httpContext, feature);

                Log.MatchSuccess(_logger, feature);
            }
            else
            {
                Log.MatchFailure(_logger);
            }

            await _next(httpContext);
        }
Example #5
0
 private static void SetFeatures(HttpContext httpContext, EndpointSelectorContext context)
 {
     // For back-compat EndpointSelectorContext implements IEndpointFeature,
     // IRouteValuesFeature and IRoutingFeature
     httpContext.Features.Set <IRoutingFeature>(context);
     httpContext.Features.Set <IRouteValuesFeature>(context);
     httpContext.Features.Set <IEndpointFeature>(context);
 }
        public void GetPathByRouteValues_UsesFirstTemplateThatSucceeds(string[] routeNames, string[] routeValues, string expectedPath)
        {
            // Arrange
            var endpointControllerAction = EndpointFactory.CreateRouteEndpoint(
                "Home/Index",
                order: 3,
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
            var endpointController = EndpointFactory.CreateRouteEndpoint(
                "Home",
                order: 2,
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
            var endpointEmpty = EndpointFactory.CreateRouteEndpoint(
                "",
                order: 1,
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });

            // This endpoint should be used to generate the link when an id is present
            var endpointControllerActionParameter = EndpointFactory.CreateRouteEndpoint(
                "Home/Index/{id}",
                order: 0,
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });

            var linkGenerator = CreateLinkGenerator(endpointControllerAction, endpointController, endpointEmpty, endpointControllerActionParameter);

            var context = new EndpointSelectorContext()
            {
                RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index", })
            };
            var httpContext = CreateHttpContext();

            httpContext.Features.Set <IRouteValuesFeature>(context);

            var values = new RouteValueDictionary();

            for (int i = 0; i < routeNames.Length; i++)
            {
                values[routeNames[i]] = routeValues[i];
            }

            // Act
            var generatedPath = linkGenerator.GetPathByRouteValues(
                httpContext,
                routeName: null,
                values: values);

            // Assert
            Assert.Equal(expectedPath, generatedPath);
        }
Example #7
0
        protected HttpContext CreateHttpContext(object ambientValues = null)
        {
            var httpContext = new DefaultHttpContext();

            var context = new EndpointSelectorContext
            {
                RouteValues = new RouteValueDictionary(ambientValues)
            };

            httpContext.Features.Set <IEndpointFeature>(context);
            httpContext.Features.Set <IRouteValuesFeature>(context);
            return(httpContext);
        }
Example #8
0
        private HttpContext CreateHttpContext()
        {
            var context = new EndpointSelectorContext();

            var httpContext = new DefaultHttpContext();

            httpContext.Features.Set <IEndpointFeature>(context);
            httpContext.Features.Set <IRouteValuesFeature>(context);

            httpContext.RequestServices = new TestServiceProvider();

            return(httpContext);
        }
        protected (HttpContext httpContext, RouteValueDictionary ambientValues) CreateCurrentRequestContext(
            object ambientValues = null)
        {
            var feature = new EndpointSelectorContext {
                RouteValues = new RouteValueDictionary(ambientValues)
            };
            var context = new DefaultHttpContext();

            context.Features.Set <IEndpointFeature>(feature);
            context.Features.Set <IRouteValuesFeature>(feature);

            return(context, feature.RouteValues);
        }
        public void RouteData_DataTokensIsEmpty_WithoutMetadata()
        {
            // Arrange
            var context = new EndpointSelectorContext()
            {
                Endpoint = new RouteEndpoint(
                    TestConstants.EmptyRequestDelegate,
                    RoutePatternFactory.Parse("/"),
                    0,
                    new EndpointMetadataCollection(),
                    "test"),
            };

            // Act
            var routeData = ((IRoutingFeature)context).RouteData;

            // Assert
            Assert.Empty(routeData.DataTokens);
        }
        public void RouteData_CanIntializeDataTokens_WithMetadata()
        {
            // Arrange
            var expected = new RouteValueDictionary(new { foo = 17, bar = "hello", });

            var context = new EndpointSelectorContext()
            {
                Endpoint = new RouteEndpoint(
                    TestConstants.EmptyRequestDelegate,
                    RoutePatternFactory.Parse("/"),
                    0,
                    new EndpointMetadataCollection(new DataTokensMetadata(expected)),
                    "test"),
            };

            // Act
            var routeData = ((IRoutingFeature)context).RouteData;

            // Assert
            Assert.NotSame(expected, routeData.DataTokens);
            Assert.Equal(expected.OrderBy(kvp => kvp.Key), routeData.DataTokens.OrderBy(kvp => kvp.Key));
        }
Example #12
0
        public void GetPathByRouteValues_WithHttpContext_UsesAmbientValues()
        {
            // Arrange
            var endpoint1 = EndpointFactory.CreateRouteEndpoint(
                "Home/Index/{id}",
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });
            var endpoint2 = EndpointFactory.CreateRouteEndpoint(
                "Home/Index/{id?}",
                defaults: new { controller = "Home", action = "Index", },
                metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) });

            var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2);

            var context = new EndpointSelectorContext()
            {
                RouteValues = new RouteValueDictionary(new { action = "Index", })
            };
            var httpContext = CreateHttpContext();

            httpContext.Features.Set <IRouteValuesFeature>(context);
            httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?");

            // Act
            var path = linkGenerator.GetPathByRouteValues(
                httpContext,
                routeName: null,
                values: new RouteValueDictionary(new { controller = "Home", query = "some?query" }),
                fragment: new FragmentString("#Fragment?"),
                options: new LinkOptions()
            {
                AppendTrailingSlash = true,
            });

            // Assert
            Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path);
        }
Example #13
0
 static async Task AwaitMatch(EndpointRoutingMiddleware middleware, HttpContext httpContext, EndpointSelectorContext feature, Task matchTask)
 {
     await matchTask;
     await middleware.SetRoutingAndContinue(httpContext, feature);
 }
Example #14
0
            // Awaited fallbacks for when the Tasks do not synchronously complete
            static async Task AwaitMatcher(EndpointRoutingMiddleware middleware, HttpContext httpContext, EndpointSelectorContext feature, Task <Matcher> matcherTask)
            {
                var matcher = await matcherTask;
                await matcher.MatchAsync(httpContext, feature);

                await middleware.SetRoutingAndContinue(httpContext, feature);
            }
Example #15
0
 public static void MatchSuccess(ILogger logger, EndpointSelectorContext context)
 {
     _matchSuccess(logger, context.Endpoint.DisplayName, null);
 }