Fix TreeMatcher with route constraints (#576)

This commit is contained in:
James Newton-King 2018-06-22 10:33:44 +12:00 committed by GitHub
parent db95a8c624
commit 6efd679ce3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 83 additions and 1 deletions

View File

@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
foreach (var kvp in constraints) foreach (var kvp in constraints)
{ {
var constraint = kvp.Value; var constraint = kvp.Value;
if (!constraint.Match(httpContext, null, kvp.Key, values, RouteDirection.IncomingRequest)) if (!constraint.Match(httpContext, new DummyRouter(), kvp.Key, values, RouteDirection.IncomingRequest))
{ {
values.TryGetValue(kvp.Key, out var value); values.TryGetValue(kvp.Key, out var value);
@ -143,6 +143,19 @@ namespace Microsoft.AspNetCore.Routing.Matchers
return true; return true;
} }
private class DummyRouter : IRouter
{
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
throw new NotImplementedException();
}
public Task RouteAsync(RouteContext context)
{
return Task.CompletedTask;
}
}
private void SelectEndpoint(HttpContext httpContext, IEndpointFeature feature, IReadOnlyList<MatcherEndpoint> endpoints) private void SelectEndpoint(HttpContext httpContext, IEndpointFeature feature, IReadOnlyList<MatcherEndpoint> endpoints)
{ {
var endpoint = (MatcherEndpoint)_endpointSelector.SelectBestCandidate(httpContext, endpoints); var endpoint = (MatcherEndpoint)_endpointSelector.SelectBestCandidate(httpContext, endpoints);

View File

@ -39,6 +39,13 @@ namespace Microsoft.AspNetCore.Routing.Matchers
return Task.CompletedTask; return Task.CompletedTask;
} }
// Route constraints not supported
[Fact]
public override Task Match_Constraint()
{
return Task.CompletedTask;
}
internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints) internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints)
{ {
var builder = new BarebonesMatcherBuilder(); var builder = new BarebonesMatcherBuilder();

View File

@ -208,6 +208,21 @@ namespace Microsoft.AspNetCore.Routing.Matchers
DispatcherAssert.AssertMatch(feature, endpoint, values); DispatcherAssert.AssertMatch(feature, endpoint, values);
} }
[Fact]
public virtual async Task Match_Constraint()
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p:int}");
var (httpContext, feature) = CreateContext("/14");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, feature);
// Assert
DispatcherAssert.AssertMatch(feature, endpoint, values);
}
[Fact] [Fact]
public virtual async Task Match_SingleParameter_TrailingSlash() public virtual async Task Match_SingleParameter_TrailingSlash()
{ {

View File

@ -32,6 +32,52 @@ namespace Microsoft.AspNetCore.Routing.Matchers
return new TreeMatcher(defaultInlineConstraintResolver, NullLogger.Instance, endpointDataSource, endpointSelector); return new TreeMatcher(defaultInlineConstraintResolver, NullLogger.Instance, endpointDataSource, endpointSelector);
} }
[Fact]
public async Task MatchAsync_ValidRouteConstraint_EndpointMatched()
{
// Arrange
var endpointDataSource = new DefaultEndpointDataSource(new List<Endpoint>
{
CreateEndpoint("/{p:int}", 0)
});
var treeMatcher = CreateTreeMatcher(endpointDataSource);
var httpContext = new DefaultHttpContext();
httpContext.Request.Path = "/1";
var endpointFeature = new EndpointFeature();
// Act
await treeMatcher.MatchAsync(httpContext, endpointFeature);
// Assert
Assert.NotNull(endpointFeature.Endpoint);
}
[Fact]
public async Task MatchAsync_InvalidRouteConstraint_NoEndpointMatched()
{
// Arrange
var endpointDataSource = new DefaultEndpointDataSource(new List<Endpoint>
{
CreateEndpoint("/{p:int}", 0)
});
var treeMatcher = CreateTreeMatcher(endpointDataSource);
var httpContext = new DefaultHttpContext();
httpContext.Request.Path = "/One";
var endpointFeature = new EndpointFeature();
// Act
await treeMatcher.MatchAsync(httpContext, endpointFeature);
// Assert
Assert.Null(endpointFeature.Endpoint);
}
[Fact] [Fact]
public async Task MatchAsync_DuplicateTemplatesAndDifferentOrder_LowerOrderEndpointMatched() public async Task MatchAsync_DuplicateTemplatesAndDifferentOrder_LowerOrderEndpointMatched()
{ {

View File

@ -21,6 +21,7 @@ namespace Microsoft.AspNetCore.Routing.Matchers
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints) internal override Matcher CreateMatcher(params MatcherEndpoint[] endpoints)
{ {
var builder = new TreeRouterMatcherBuilder(); var builder = new TreeRouterMatcherBuilder();