Fix TreeMatcher with route constraints (#576)
This commit is contained in:
parent
db95a8c624
commit
6efd679ce3
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue