Clear route values after middleware invocation.

#11233
This commit is contained in:
N. Taylor Mullen 2019-07-19 14:33:43 -07:00
parent 479d5ed40a
commit c54a7209d7
3 changed files with 65 additions and 29 deletions

View File

@ -3,10 +3,10 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Matching; using Microsoft.AspNetCore.Routing.Matching;
using Microsoft.Extensions.Logging; 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. // This allows a second call in a single request (such as from the ErrorHandlerMiddleware) to perform routing again.
httpContext.SetEndpoint(endpoint: null); httpContext.SetEndpoint(endpoint: null);
var routeValuesFeature = httpContext.Features.Get<IRouteValuesFeature>();
routeValuesFeature?.RouteValues?.Clear();
} }
} }

View File

@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Builder
} }
[Fact] [Fact]
public async Task UseRouting_ServicesRegistered_Match_DoesNotSetsFeature() public async Task UseRouting_ServicesRegistered_Match_DoesNotSetFeature()
{ {
// Arrange // Arrange
var endpoint = new RouteEndpoint( var endpoint = new RouteEndpoint(
@ -104,7 +104,6 @@ namespace Microsoft.AspNetCore.Builder
// Assert // Assert
var feature = httpContext.Features.Get<IEndpointFeature>(); var feature = httpContext.Features.Get<IEndpointFeature>();
Assert.NotNull(feature); Assert.NotNull(feature);
Assert.Same(endpoint, httpContext.GetEndpoint());
} }
[Fact] [Fact]

View File

@ -102,6 +102,26 @@ namespace Microsoft.AspNetCore.Routing
Assert.Null(endpointFeature.Endpoint); 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<IRoutingFeature>(new RoutingFeature()
{
RouteData = initialRouteData,
});
var middleware = CreateMiddleware();
// Act
await middleware.Invoke(httpContext);
// Assert
Assert.Null(httpContext.GetRouteValue("test"));
}
[Fact] [Fact]
public async Task Invoke_SkipsRoutingAndMaintainsEndpoint_IfEndpointSet() public async Task Invoke_SkipsRoutingAndMaintainsEndpoint_IfEndpointSet()
{ {
@ -162,22 +182,29 @@ namespace Microsoft.AspNetCore.Routing
{ {
// Arrange // Arrange
var httpContext = CreateHttpContext(); 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<IRouteValuesFeature>();
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); await middleware.Invoke(httpContext);
var routeData = httpContext.GetRouteData(); Assert.True(nextCalled);
var routeValue = httpContext.GetRouteValue("controller");
var routeValuesFeature = httpContext.Features.Get<IRouteValuesFeature>();
// 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"]);
} }
[Fact] [Fact]
@ -185,22 +212,29 @@ namespace Microsoft.AspNetCore.Routing
{ {
// Arrange // Arrange
var httpContext = CreateHttpContext(); 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<IRouteValuesFeature>();
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); await middleware.Invoke(httpContext);
var routeData = httpContext.GetRouteData(); Assert.True(called);
var routeValue = httpContext.GetRouteValue("controller");
var routeValuesFeature = httpContext.Features.Get<IRouteValuesFeature>();
// 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"]);
} }
[Fact] [Fact]