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); }
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));
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); }
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); }
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); }
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); }
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)); }
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); }
static async Task AwaitMatch(EndpointRoutingMiddleware middleware, HttpContext httpContext, EndpointSelectorContext feature, Task matchTask) { await matchTask; await middleware.SetRoutingAndContinue(httpContext, feature); }
// 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); }
public static void MatchSuccess(ILogger logger, EndpointSelectorContext context) { _matchSuccess(logger, context.Endpoint.DisplayName, null); }