From c54a7209d7bc41e163ca8767e59765fbc37d27ce Mon Sep 17 00:00:00 2001 From: "N. Taylor Mullen" Date: Fri, 19 Jul 2019 14:33:43 -0700 Subject: [PATCH] Clear route values after middleware invocation. #11233 --- .../Routing/src/EndpointRoutingMiddleware.cs | 5 +- ...RoutingApplicationBuilderExtensionsTest.cs | 3 +- .../EndpointRoutingMiddlewareTest.cs | 86 +++++++++++++------ 3 files changed, 65 insertions(+), 29 deletions(-) diff --git a/src/Http/Routing/src/EndpointRoutingMiddleware.cs b/src/Http/Routing/src/EndpointRoutingMiddleware.cs index 65596ecfd4..4ae20514d2 100644 --- a/src/Http/Routing/src/EndpointRoutingMiddleware.cs +++ b/src/Http/Routing/src/EndpointRoutingMiddleware.cs @@ -3,10 +3,10 @@ using System; using System.Diagnostics; -using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Routing.Matching; using Microsoft.Extensions.Logging; @@ -116,6 +116,9 @@ namespace Microsoft.AspNetCore.Routing { // This allows a second call in a single request (such as from the ErrorHandlerMiddleware) to perform routing again. httpContext.SetEndpoint(endpoint: null); + + var routeValuesFeature = httpContext.Features.Get(); + routeValuesFeature?.RouteValues?.Clear(); } } diff --git a/src/Http/Routing/test/UnitTests/Builder/EndpointRoutingApplicationBuilderExtensionsTest.cs b/src/Http/Routing/test/UnitTests/Builder/EndpointRoutingApplicationBuilderExtensionsTest.cs index 7f51f6e9a7..e1451329ea 100644 --- a/src/Http/Routing/test/UnitTests/Builder/EndpointRoutingApplicationBuilderExtensionsTest.cs +++ b/src/Http/Routing/test/UnitTests/Builder/EndpointRoutingApplicationBuilderExtensionsTest.cs @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Builder } [Fact] - public async Task UseRouting_ServicesRegistered_Match_DoesNotSetsFeature() + public async Task UseRouting_ServicesRegistered_Match_DoesNotSetFeature() { // Arrange var endpoint = new RouteEndpoint( @@ -104,7 +104,6 @@ namespace Microsoft.AspNetCore.Builder // Assert var feature = httpContext.Features.Get(); Assert.NotNull(feature); - Assert.Same(endpoint, httpContext.GetEndpoint()); } [Fact] diff --git a/src/Http/Routing/test/UnitTests/EndpointRoutingMiddlewareTest.cs b/src/Http/Routing/test/UnitTests/EndpointRoutingMiddlewareTest.cs index c3cf38cc32..8f97bfd5d2 100644 --- a/src/Http/Routing/test/UnitTests/EndpointRoutingMiddlewareTest.cs +++ b/src/Http/Routing/test/UnitTests/EndpointRoutingMiddlewareTest.cs @@ -102,6 +102,26 @@ namespace Microsoft.AspNetCore.Routing Assert.Null(endpointFeature.Endpoint); } + [Fact] + public async Task Invoke_OnCall_SetsEndpointFeatureAndResetsRouteValues() + { + // Arrange + var httpContext = CreateHttpContext(); + var initialRouteData = new RouteData(); + initialRouteData.Values["test"] = true; + httpContext.Features.Set(new RoutingFeature() + { + RouteData = initialRouteData, + }); + var middleware = CreateMiddleware(); + + // Act + await middleware.Invoke(httpContext); + + // Assert + Assert.Null(httpContext.GetRouteValue("test")); + } + [Fact] public async Task Invoke_SkipsRoutingAndMaintainsEndpoint_IfEndpointSet() { @@ -162,22 +182,29 @@ namespace Microsoft.AspNetCore.Routing { // Arrange var httpContext = CreateHttpContext(); + var nextCalled = false; - var middleware = CreateMiddleware(); + var middleware = CreateMiddleware(next: context => + { + var routeData = httpContext.GetRouteData(); + var routeValue = httpContext.GetRouteValue("controller"); + var routeValuesFeature = httpContext.Features.Get(); + nextCalled = true; - // Act + // Assert + Assert.NotNull(routeData); + Assert.Equal("Home", (string)routeValue); + + // changing route data value is reflected in endpoint feature values + routeData.Values["testKey"] = "testValue"; + Assert.Equal("testValue", routeValuesFeature.RouteValues["testKey"]); + + return Task.CompletedTask; + }); + + // Act & Assert await middleware.Invoke(httpContext); - var routeData = httpContext.GetRouteData(); - var routeValue = httpContext.GetRouteValue("controller"); - var routeValuesFeature = httpContext.Features.Get(); - - // Assert - Assert.NotNull(routeData); - Assert.Equal("Home", (string)routeValue); - - // changing route data value is reflected in endpoint feature values - routeData.Values["testKey"] = "testValue"; - Assert.Equal("testValue", routeValuesFeature.RouteValues["testKey"]); + Assert.True(nextCalled); } [Fact] @@ -185,22 +212,29 @@ namespace Microsoft.AspNetCore.Routing { // Arrange var httpContext = CreateHttpContext(); + var called = false; - var middleware = CreateMiddleware(); + var middleware = CreateMiddleware(next: context => + { + var routeData = httpContext.GetRouteData(); + var routeValue = httpContext.GetRouteValue("controller"); + var routeValuesFeature = httpContext.Features.Get(); + called = true; - // Act + // Assert + Assert.NotNull(routeData); + Assert.Equal("Home", (string)routeValue); + + // changing route data value is reflected in endpoint feature values + routeData.Values["testKey"] = "testValue"; + Assert.Equal("testValue", routeValuesFeature.RouteValues["testKey"]); + + return Task.CompletedTask; + }); + + // Act & Assert await middleware.Invoke(httpContext); - var routeData = httpContext.GetRouteData(); - var routeValue = httpContext.GetRouteValue("controller"); - var routeValuesFeature = httpContext.Features.Get(); - - // Assert - Assert.NotNull(routeData); - Assert.Equal("Home", (string)routeValue); - - // changing route data value is reflected in endpoint feature values - routeData.Values["testKey"] = "testValue"; - Assert.Equal("testValue", routeValuesFeature.RouteValues["testKey"]); + Assert.True(called); } [Fact]