Fix TreeMatcher's use of EndpointSelector (#551)

This commit is contained in:
James Newton-King 2018-06-12 15:47:34 +12:00 коммит произвёл GitHub
Родитель 84bc8351c9
Коммит 28d1bc4fa2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 55 добавлений и 30 удалений

Просмотреть файл

@ -141,37 +141,31 @@ namespace Microsoft.AspNetCore.Routing.Matchers
private Task SelectEndpointAsync(HttpContext httpContext, IEndpointFeature feature, IReadOnlyList<MatcherEndpoint> endpoints)
{
var bestEndpoint = _endpointSelector.SelectBestCandidate(httpContext, endpoints);
MatcherEndpoint endpoint;
// REVIEW: Note that this code doesn't do anything significant now. This will eventually incorporate something like IActionConstraint
switch (endpoints.Count)
try
{
case 0:
{
Log.MatchFailed(_logger, httpContext);
return Task.CompletedTask;
}
case 1:
{
var endpoint = endpoints[0];
Log.MatchSuccess(_logger, httpContext, endpoint);
feature.Endpoint = endpoint;
feature.Invoker = endpoint.Invoker;
return Task.CompletedTask;
}
default:
{
Log.MatchAmbiguous(_logger, httpContext, endpoints);
var message = Resources.FormatAmbiguousEndpoints(
Environment.NewLine,
string.Join(Environment.NewLine, endpoints.Select(a => a.DisplayName)));
throw new AmbiguousMatchException(message);
}
endpoint = (MatcherEndpoint)_endpointSelector.SelectBestCandidate(httpContext, endpoints);
}
catch (Exception ex)
{
// Handle AmbiguousMatchException from EndpointSelector
return Task.FromException(ex);
}
if (endpoint == null)
{
Log.MatchFailed(_logger, httpContext);
}
else
{
Log.MatchSuccess(_logger, httpContext, endpoint);
feature.Endpoint = endpoint;
feature.Invoker = endpoint.Invoker;
}
return Task.CompletedTask;
}
private UrlMatchingTree[] CreateTrees(IReadOnlyList<Endpoint> endpoints)

Просмотреть файл

@ -15,9 +15,9 @@ namespace Microsoft.AspNetCore.Routing.Matchers
{
public class TreeMatcherTests
{
private MatcherEndpoint CreateEndpoint(string template, int order, object values = null)
private MatcherEndpoint CreateEndpoint(string template, int order, object values = null, EndpointMetadataCollection metadata = null)
{
return new MatcherEndpoint((next) => null, template, values, order, EndpointMetadataCollection.Empty, template);
return new MatcherEndpoint((next) => null, template, values, order, metadata ?? EndpointMetadataCollection.Empty, template);
}
private TreeMatcher CreateTreeMatcher(EndpointDataSource endpointDataSource)
@ -58,5 +58,36 @@ namespace Microsoft.AspNetCore.Routing.Matchers
// Assert
Assert.Equal(lowerOrderEndpoint, endpointFeature.Endpoint);
}
[Fact]
public async Task MatchAsync_MultipleMatches_EndpointSelectorCalled()
{
// Arrange
var endpointWithoutConstraint = CreateEndpoint("/Teams", 0);
var endpointWithConstraint = CreateEndpoint(
"/Teams",
0,
metadata: new EndpointMetadataCollection(new object[] { new HttpMethodEndpointConstraint(new[] { "POST" }) }));
var endpointDataSource = new DefaultEndpointDataSource(new List<Endpoint>
{
endpointWithoutConstraint,
endpointWithConstraint
});
var treeMatcher = CreateTreeMatcher(endpointDataSource);
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "POST";
httpContext.Request.Path = "/Teams";
var endpointFeature = new EndpointFeature();
// Act
await treeMatcher.MatchAsync(httpContext, endpointFeature);
// Assert
Assert.Equal(endpointWithConstraint, endpointFeature.Endpoint);
}
}
}