Remove EndpointSelectorContext

This commit is contained in:
Ryan Nowak 2019-05-07 20:40:41 -07:00 committed by Ryan Nowak
parent a36a57df65
commit 0a1d68b8f3
45 changed files with 514 additions and 654 deletions

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Http.Abstractions.Tests
// Assert
var feature = context.Features.Get<IEndpointFeature>();
Assert.NotNull(feature);
Assert.Equal(endpoint, feature.Endpoint);
Assert.Equal(endpoint, context.GetEndpoint());
}
[Fact]
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Http.Abstractions.Tests
// Assert
var feature = context.Features.Get<IEndpointFeature>();
Assert.Equal(initialFeature, feature);
Assert.Equal(endpoint, feature.Endpoint);
Assert.Equal(endpoint, context.GetEndpoint());
}
[Fact]
@ -130,7 +130,7 @@ namespace Microsoft.AspNetCore.Http.Abstractions.Tests
// Assert
var feature = context.Features.Get<IEndpointFeature>();
Assert.Equal(initialFeature, feature);
Assert.Null(feature.Endpoint);
Assert.Null(context.GetEndpoint());
}
[Fact]

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;

View File

@ -3,6 +3,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Http.Endpoints;
namespace Microsoft.AspNetCore.Routing.Matching
{
@ -15,7 +16,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
private Matcher _dfa;
private int[] _samples;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
@ -30,34 +30,30 @@ namespace Microsoft.AspNetCore.Routing.Matching
_baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
_dfa = SetupMatcher(CreateDfaMatcherBuilder());
_feature = new EndpointSelectorContext();
}
[Benchmark(Baseline = true, OperationsPerInvoke = SampleCount)]
public async Task Baseline()
{
var feature = _feature;
for (var i = 0; i < SampleCount; i++)
{
var sample = _samples[i];
var httpContext = Requests[sample];
await _baseline.Matchers[sample].MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[sample], feature.Endpoint);
await _baseline.Matchers[sample].MatchAsync(httpContext);
Validate(httpContext, Endpoints[sample], httpContext.GetEndpoint());
}
}
[Benchmark(OperationsPerInvoke = SampleCount)]
public async Task Dfa()
{
var feature = _feature;
for (var i = 0; i < SampleCount; i++)
{
var sample = _samples[i];
var httpContext = Requests[sample];
await _dfa.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[sample], feature.Endpoint);
await _dfa.MatchAsync(httpContext);
Validate(httpContext, Endpoints[sample], httpContext.GetEndpoint());
}
}
}
}
}

View File

@ -162,7 +162,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return false;
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
throw new NotImplementedException();
}
@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return false;
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
throw new NotImplementedException();
}

View File

@ -3,6 +3,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
@ -14,8 +15,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
private BarebonesMatcher _baseline;
private Matcher _dfa;
private EndpointSelectorContext _feature;
[GlobalSetup]
public void Setup()
{
@ -25,32 +24,28 @@ namespace Microsoft.AspNetCore.Routing.Matching
_baseline = (BarebonesMatcher)SetupMatcher(new BarebonesMatcherBuilder());
_dfa = SetupMatcher(CreateDfaMatcherBuilder());
_feature = new EndpointSelectorContext();
}
[Benchmark(Baseline = true, OperationsPerInvoke = EndpointCount)]
public async Task Baseline()
{
var feature = _feature;
for (var i = 0; i < EndpointCount; i++)
{
var httpContext = Requests[i];
await _baseline.Matchers[i].MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[i], feature.Endpoint);
await _baseline.Matchers[i].MatchAsync(httpContext);
Validate(httpContext, Endpoints[i], httpContext.GetEndpoint());
}
}
[Benchmark( OperationsPerInvoke = EndpointCount)]
public async Task Dfa()
{
var feature = _feature;
for (var i = 0; i < EndpointCount; i++)
{
var httpContext = Requests[i];
await _dfa.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[i], feature.Endpoint);
await _dfa.MatchAsync(httpContext);
Validate(httpContext, Endpoints[i], httpContext.GetEndpoint());
}
}
}
}
}

View File

@ -4,6 +4,7 @@
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
@ -43,40 +44,36 @@ namespace Microsoft.AspNetCore.Routing.Matching
public async Task Baseline()
{
var httpContext = Requests[0];
var feature = new EndpointSelectorContext(httpContext);
await _baseline.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[0], feature.Endpoint);
await _baseline.MatchAsync(httpContext);
Validate(httpContext, Endpoints[0], httpContext.GetEndpoint());
}
[Benchmark]
public async Task Dfa()
{
var httpContext = Requests[0];
var feature = new EndpointSelectorContext(httpContext);
await _dfa.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[0], feature.Endpoint);
await _dfa.MatchAsync(httpContext);
Validate(httpContext, Endpoints[0], httpContext.GetEndpoint());
}
[Benchmark]
public async Task LegacyTreeRouter()
{
var httpContext = Requests[0];
var feature = new EndpointSelectorContext(httpContext);
await _tree.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[0], feature.Endpoint);
await _tree.MatchAsync(httpContext);
Validate(httpContext, Endpoints[0], httpContext.GetEndpoint());
}
[Benchmark]
public async Task LegacyRouter()
{
var httpContext = Requests[0];
var feature = new EndpointSelectorContext(httpContext);
await _route.MatchAsync(httpContext, feature);
Validate(httpContext, Endpoints[0], feature.Endpoint);
await _route.MatchAsync(httpContext);
Validate(httpContext, Endpoints[0], httpContext.GetEndpoint());
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_candidates = new Candidate[] { new Candidate(endpoint), };
}
public sealed override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public sealed override Task MatchAsync(HttpContext httpContext)
{
if (httpContext == null)
{
@ -33,8 +34,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
var path = httpContext.Request.Path.Value;
if (string.Equals(_endpoint.RoutePattern.RawText, path, StringComparison.OrdinalIgnoreCase))
{
context.Endpoint = _endpoint;
context.RouteValues = new RouteValueDictionary();
httpContext.SetEndpoint(_endpoint);
httpContext.Request.RouteValues = new RouteValueDictionary();
}
return Task.CompletedTask;

View File

@ -89,14 +89,6 @@ namespace Microsoft.AspNetCore.Routing
public EndpointNameMetadata(string endpointName) { }
public string EndpointName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct EndpointSelectorContext
{
private readonly object _dummy;
public EndpointSelectorContext(Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; }
public Microsoft.AspNetCore.Http.Endpoint Endpoint { get { throw null; } set { } }
public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get { throw null; } set { } }
}
[System.AttributeUsageAttribute(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=false, Inherited=false)]
[System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")]
public sealed partial class HostAttribute : System.Attribute, Microsoft.AspNetCore.Routing.IHostMetadata
@ -572,14 +564,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
public abstract partial class EndpointSelector
{
protected EndpointSelector() { }
public abstract System.Threading.Tasks.Task SelectAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.EndpointSelectorContext context, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates);
public abstract System.Threading.Tasks.Task SelectAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates);
}
public sealed partial class HostMatcherPolicy : Microsoft.AspNetCore.Routing.MatcherPolicy, Microsoft.AspNetCore.Routing.Matching.IEndpointComparerPolicy, Microsoft.AspNetCore.Routing.Matching.IEndpointSelectorPolicy, Microsoft.AspNetCore.Routing.Matching.INodeBuilderPolicy
{
public HostMatcherPolicy() { }
public System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint> Comparer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public override int Order { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
public System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.EndpointSelectorContext context, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates) { throw null; }
public System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates) { throw null; }
public Microsoft.AspNetCore.Routing.Matching.PolicyJumpTable BuildJumpTable(int exitDestination, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Routing.Matching.PolicyJumpTableEdge> edges) { throw null; }
public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Routing.Matching.PolicyNodeEdge> GetEdges(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.Endpoint> endpoints) { throw null; }
bool Microsoft.AspNetCore.Routing.Matching.IEndpointSelectorPolicy.AppliesToEndpoints(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.Endpoint> endpoints) { throw null; }
@ -590,7 +582,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
public HttpMethodMatcherPolicy() { }
public System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint> Comparer { get { throw null; } }
public override int Order { get { throw null; } }
public System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.EndpointSelectorContext context, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates) { throw null; }
public System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates) { throw null; }
public Microsoft.AspNetCore.Routing.Matching.PolicyJumpTable BuildJumpTable(int exitDestination, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Routing.Matching.PolicyJumpTableEdge> edges) { throw null; }
public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Routing.Matching.PolicyNodeEdge> GetEdges(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.Endpoint> endpoints) { throw null; }
bool Microsoft.AspNetCore.Routing.Matching.IEndpointSelectorPolicy.AppliesToEndpoints(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.Endpoint> endpoints) { throw null; }
@ -603,7 +595,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
public partial interface IEndpointSelectorPolicy
{
bool AppliesToEndpoints(System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.Endpoint> endpoints);
System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.EndpointSelectorContext context, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates);
System.Threading.Tasks.Task ApplyAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.Matching.CandidateSet candidates);
}
public partial interface INodeBuilderPolicy
{

View File

@ -6,6 +6,7 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Routing.Matching;
using Microsoft.Extensions.Logging;
@ -55,12 +56,11 @@ namespace Microsoft.AspNetCore.Routing
public Task Invoke(HttpContext httpContext)
{
var feature = new EndpointSelectorContext(httpContext);
// There's already an endpoint, skip maching completely
if (feature.Endpoint != null)
var endpoint = httpContext.GetEndpoint();
if (endpoint != null)
{
Log.MatchSkipped(_logger, feature.Endpoint);
Log.MatchSkipped(_logger, endpoint);
return _next(httpContext);
}
@ -69,44 +69,45 @@ namespace Microsoft.AspNetCore.Routing
var matcherTask = InitializeAsync();
if (!matcherTask.IsCompletedSuccessfully)
{
return AwaitMatcher(this, httpContext, feature, matcherTask);
return AwaitMatcher(this, httpContext, matcherTask);
}
var matchTask = matcherTask.Result.MatchAsync(httpContext, feature);
var matchTask = matcherTask.Result.MatchAsync(httpContext);
if (!matchTask.IsCompletedSuccessfully)
{
return AwaitMatch(this, httpContext, feature, matchTask);
return AwaitMatch(this, httpContext, matchTask);
}
return SetRoutingAndContinue(httpContext, feature);
return SetRoutingAndContinue(httpContext);
// Awaited fallbacks for when the Tasks do not synchronously complete
static async Task AwaitMatcher(EndpointRoutingMiddleware middleware, HttpContext httpContext, EndpointSelectorContext feature, Task<Matcher> matcherTask)
static async Task AwaitMatcher(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task<Matcher> matcherTask)
{
var matcher = await matcherTask;
await matcher.MatchAsync(httpContext, feature);
await middleware.SetRoutingAndContinue(httpContext, feature);
await matcher.MatchAsync(httpContext);
await middleware.SetRoutingAndContinue(httpContext);
}
static async Task AwaitMatch(EndpointRoutingMiddleware middleware, HttpContext httpContext, EndpointSelectorContext feature, Task matchTask)
static async Task AwaitMatch(EndpointRoutingMiddleware middleware, HttpContext httpContext, Task matchTask)
{
await matchTask;
await middleware.SetRoutingAndContinue(httpContext, feature);
await middleware.SetRoutingAndContinue(httpContext);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private Task SetRoutingAndContinue(HttpContext httpContext, EndpointSelectorContext feature)
private Task SetRoutingAndContinue(HttpContext httpContext)
{
// If there was no mutation of the endpoint then log failure
if (feature.Endpoint is null)
var endpoint = httpContext.GetEndpoint();
if (endpoint == null)
{
Log.MatchFailure(_logger);
}
else
{
Log.MatchSuccess(_logger, feature);
Log.MatchSuccess(_logger, endpoint);
}
return _next(httpContext);
@ -115,8 +116,8 @@ namespace Microsoft.AspNetCore.Routing
// Initialization is async to avoid blocking threads while reflection and things
// of that nature take place.
//
// We've seen cases where startup is very slow if we allow multiple threads to race
// while initializing the set of endpoints/routes. Doing CPU intensive work is a
// We've seen cases where startup is very slow if we allow multiple threads to race
// while initializing the set of endpoints/routes. Doing CPU intensive work is a
// blocking operation if you have a low core count and enough work to do.
private Task<Matcher> InitializeAsync()
{
@ -184,9 +185,9 @@ namespace Microsoft.AspNetCore.Routing
new EventId(3, "MatchingSkipped"),
"Endpoint '{EndpointName}' already set, skipping route matching.");
public static void MatchSuccess(ILogger logger, EndpointSelectorContext context)
public static void MatchSuccess(ILogger logger, Endpoint endpoint)
{
_matchSuccess(logger, context.Endpoint.DisplayName, null);
_matchSuccess(logger, endpoint.DisplayName, null);
}
public static void MatchFailure(ILogger logger)

View File

@ -1,51 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
namespace Microsoft.AspNetCore.Routing
{
public readonly struct EndpointSelectorContext
{
private readonly HttpContext _httpContext;
public EndpointSelectorContext(HttpContext httpContext)
{
_httpContext = httpContext ?? throw new ArgumentNullException(nameof(httpContext));
}
/// <summary>
/// Gets or sets the selected <see cref="Http.Endpoint"/> for the current
/// request.
/// </summary>
public Endpoint Endpoint
{
get
{
return _httpContext.GetEndpoint();
}
set
{
_httpContext.SetEndpoint(value);
}
}
/// <summary>
/// Gets or sets the <see cref="RouteValueDictionary"/> associated with the currrent
/// request.
/// </summary>
public RouteValueDictionary RouteValues
{
get
{
return _httpContext.Request.RouteValues;
}
set
{
_httpContext.Request.RouteValues = value;
}
}
}
}

View File

@ -31,9 +31,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Used in tests
internal Matcher CurrentMatcher => _cache.Value;
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public override Task MatchAsync(HttpContext httpContext)
{
return CurrentMatcher.MatchAsync(httpContext, context);
return CurrentMatcher.MatchAsync(httpContext);
}
private Matcher CreateMatcher(IReadOnlyList<Endpoint> endpoints)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
namespace Microsoft.AspNetCore.Routing.Matching
{
@ -13,7 +14,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
public override Task SelectAsync(
HttpContext httpContext,
EndpointSelectorContext context,
CandidateSet candidateSet)
{
if (httpContext == null)
@ -26,14 +26,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
throw new ArgumentNullException(nameof(candidateSet));
}
Select(httpContext, context, candidateSet.Candidates);
Select(httpContext, candidateSet.Candidates);
return Task.CompletedTask;
}
internal static void Select(
HttpContext httpContext,
EndpointSelectorContext context,
CandidateState[] candidateState)
internal static void Select(HttpContext httpContext, CandidateState[] candidateState)
{
// Fast path: We can specialize for trivial numbers of candidates since there can
// be no ambiguities
@ -50,8 +47,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
ref var state = ref candidateState[0];
if (CandidateSet.IsValidCandidate(ref state))
{
context.Endpoint = state.Endpoint;
context.RouteValues = state.Values;
httpContext.SetEndpoint(state.Endpoint);
httpContext.Request.RouteValues = state.Values;
}
break;
@ -61,7 +58,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Slow path: There's more than one candidate (to say nothing of validity) so we
// have to process for ambiguities.
ProcessFinalCandidates(httpContext, context, candidateState);
ProcessFinalCandidates(httpContext, candidateState);
break;
}
}
@ -69,7 +66,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
private static void ProcessFinalCandidates(
HttpContext httpContext,
EndpointSelectorContext context,
CandidateState[] candidateState)
{
Endpoint endpoint = null;
@ -100,7 +96,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
else if (foundScore == state.Score)
{
// This is the second match we've found of the same score, so there
// This is the second match we've found of the same score, so there
// must be an ambiguity.
//
// Don't worry about the 'null == state.Score' case, it returns false.
@ -114,8 +110,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (endpoint != null)
{
context.Endpoint = endpoint;
context.RouteValues = values;
httpContext.SetEndpoint(endpoint);
httpContext.Request.RouteValues = values;
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.Extensions.Logging;
@ -27,7 +28,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_isDefaultEndpointSelector = selector is DefaultEndpointSelector;
}
public sealed override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public sealed override Task MatchAsync(HttpContext httpContext)
{
if (httpContext == null)
{
@ -73,10 +74,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
ref readonly var candidate = ref candidates[0];
// Just strict path matching
// Just strict path matching (no route values)
if (candidate.Flags == Candidate.CandidateFlags.None)
{
context.Endpoint = candidate.Endpoint;
httpContext.SetEndpoint(candidate.Endpoint);
// We're done
return Task.CompletedTask;
@ -181,7 +182,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Fast path that avoids allocating the candidate set.
//
// We can use this when there are no policies and we're using the default selector.
DefaultEndpointSelector.Select(httpContext, context, candidateState);
DefaultEndpointSelector.Select(httpContext, candidateState);
return Task.CompletedTask;
}
else if (policyCount == 0)
@ -189,10 +190,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Fast path that avoids a state machine.
//
// We can use this when there are no policies and a non-default selector.
return _selector.SelectAsync(httpContext, context, new CandidateSet(candidateState));
return _selector.SelectAsync(httpContext, new CandidateSet(candidateState));
}
return SelectEndpointWithPoliciesAsync(httpContext, context, policies, new CandidateSet(candidateState));
return SelectEndpointWithPoliciesAsync(httpContext, policies, new CandidateSet(candidateState));
}
internal (Candidate[] candidates, IEndpointSelectorPolicy[] policies) FindCandidateSet(
@ -304,22 +305,21 @@ namespace Microsoft.AspNetCore.Routing.Matching
private async Task SelectEndpointWithPoliciesAsync(
HttpContext httpContext,
EndpointSelectorContext context,
IEndpointSelectorPolicy[] policies,
CandidateSet candidateSet)
{
for (var i = 0; i < policies.Length; i++)
{
var policy = policies[i];
await policy.ApplyAsync(httpContext, context, candidateSet);
if (context.Endpoint != null)
await policy.ApplyAsync(httpContext, candidateSet);
if (httpContext.GetEndpoint() != null)
{
// This is a short circuit, the selector chose an endpoint.
return;
}
}
await _selector.SelectAsync(httpContext, context, candidateSet);
await _selector.SelectAsync(httpContext, candidateSet);
}
internal static class EventIds

View File

@ -1,9 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Http.Endpoints;
namespace Microsoft.AspNetCore.Routing.Matching
{
@ -18,16 +18,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// Asynchronously selects an <see cref="Endpoint"/> from the <see cref="CandidateSet"/>.
/// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="context">The <see cref="EndpointSelectorContext"/> associated with the current request.</param>
/// <param name="candidates">The <see cref="CandidateSet"/>.</param>
/// <returns>A <see cref="Task"/> that completes asynchronously once endpoint selection is complete.</returns>
/// <remarks>
/// An <see cref="EndpointSelector"/> should assign the <see cref="EndpointSelectorContext.Endpoint"/>
/// and <see cref="EndpointSelectorContext.RouteValues"/> properties once an endpoint is selected.
/// An <see cref="EndpointSelector"/> should assign the endpoint by calling
/// <see cref="EndpointHttpContextExtensions.SetEndpoint(HttpContext, Endpoint)"/>
/// and setting <see cref="HttpRequest.RouteValues"/> once an endpoint is selected.
/// </remarks>
public abstract Task SelectAsync(
HttpContext httpContext,
EndpointSelectorContext context,
CandidateSet candidates);
public abstract Task SelectAsync(HttpContext httpContext, CandidateSet candidates);
}
}

View File

@ -70,7 +70,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
});
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
@ -84,10 +85,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// For framework use only.
/// </summary>
/// <param name="httpContext"></param>
/// <param name="context"></param>
/// <param name="candidates"></param>
/// <returns></returns>
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{
@ -168,7 +168,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (needs405Endpoint == true)
{
// We saw some endpoints coming in, and we eliminated them all.
context.Endpoint = CreateRejectionEndpoint(methods.OrderBy(m => m, StringComparer.OrdinalIgnoreCase));
httpContext.SetEndpoint(CreateRejectionEndpoint(methods.OrderBy(m => m, StringComparer.OrdinalIgnoreCase)));
httpContext.Request.RouteValues = null;
}
return Task.CompletedTask;
@ -294,7 +295,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
// unlikely in a traditional MVC application. That's good.
//
// We don't bother returning a 405 when the CORS preflight method doesn't exist.
// The developer calling the API will see it as a CORS error, which is fine because
// The developer calling the API will see it as a CORS error, which is fine because
// there isn't an endpoint to check for a CORS policy.
if (!edges.TryGetValue(new EdgeKey(AnyMethod, false), out var matches))
{

View File

@ -1,7 +1,8 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using System.Collections.Generic;
using System.Threading.Tasks;
@ -31,9 +32,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <param name="httpContext">
/// The <see cref="HttpContext"/> associated with the current request.
/// </param>
/// <param name="context">
/// The <see cref="EndpointSelectorContext"/> associated with the current request.
/// </param>
/// <param name="candidates">The <see cref="CandidateSet"/>.</param>
/// <remarks>
/// <para>
@ -42,10 +40,12 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <see cref="CandidateSet.SetValidity(int, bool)"/> to <c>false</c> where desired.
/// </para>
/// <para>
/// To signal an error condition, set <see cref="EndpointSelectorContext.Endpoint"/> to an
/// To signal an error condition, the <see cref="IEndpointSelectorPolicy"/> should assign the endpoint by
/// calling <see cref="EndpointHttpContextExtensions.SetEndpoint(HttpContext, Endpoint)"/>
/// and setting <see cref="HttpRequest.RouteValues"/> to an
/// <see cref="Endpoint"/> value that will produce the desired error when executed.
/// </para>
/// </remarks>
Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates);
Task ApplyAsync(HttpContext httpContext, CandidateSet candidates);
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
@ -17,10 +17,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// Attempts to asynchronously select an <see cref="Endpoint"/> for the current request.
/// </summary>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="context">
/// The <see cref="IEndpointFeature"/> associated with the current request. The
/// <see cref="EndpointSelectorContext"/> will be mutated to contain the result of the operation.</param>
/// <returns>A <see cref="Task"/> which represents the asynchronous completion of the operation.</returns>
public abstract Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context);
public abstract Task MatchAsync(HttpContext httpContext);
}
}

View File

@ -105,7 +105,7 @@ namespace Microsoft.AspNetCore.Builder
// Assert
var feature = httpContext.Features.Get<IEndpointFeature>();
Assert.NotNull(feature);
Assert.Same(endpoint, feature.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
}
[Fact]

View File

@ -1,53 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Routing.Patterns;
using Xunit;
namespace Microsoft.AspNetCore.Routing
{
public class EndpointSelectorContextTest
{
[Fact]
public void SettingEndpointSetsEndpointOnHttpContext()
{
var httpContext = new DefaultHttpContext();
var ep = new RouteEndpoint(
TestConstants.EmptyRequestDelegate,
RoutePatternFactory.Parse("/"),
0,
new EndpointMetadataCollection(),
"test");
new EndpointSelectorContext(httpContext)
{
Endpoint = ep,
};
// Assert
var endpoint = httpContext.GetEndpoint();
Assert.NotNull(endpoint);
Assert.Same(ep, endpoint);
}
[Fact]
public void SettingRouteValuesSetRouteValuesHttpContext()
{
var httpContext = new DefaultHttpContext();
var routeValues = new RouteValueDictionary(new { A = "1" });
new EndpointSelectorContext(httpContext)
{
RouteValues = routeValues
};
// Assert
Assert.NotNull(httpContext.Request.RouteValues);
Assert.Same(routeValues, httpContext.Request.RouteValues);
Assert.Single(httpContext.Request.RouteValues);
Assert.Equal("1", httpContext.Request.RouteValues["A"]);
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
namespace Microsoft.AspNetCore.Routing.Matching
@ -20,7 +21,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Matchers = matchers;
}
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public override Task MatchAsync(HttpContext httpContext)
{
if (httpContext == null)
{
@ -32,8 +33,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
if (Matchers[i].TryMatch(path))
{
context.Endpoint = Matchers[i].Endpoint;
context.RouteValues = new RouteValueDictionary();
httpContext.SetEndpoint(Matchers[i].Endpoint);
httpContext.Request.RouteValues = new RouteValueDictionary();
}
}
@ -116,12 +117,12 @@ namespace Microsoft.AspNetCore.Routing.Matching
return Array.Empty<Candidate>();
}
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public override Task MatchAsync(HttpContext httpContext)
{
if (TryMatch(httpContext.Request.Path.Value))
{
context.Endpoint = Endpoint;
context.RouteValues = new RouteValueDictionary();
httpContext.SetEndpoint(Endpoint);
httpContext.Request.RouteValues = new RouteValueDictionary();
}
return Task.CompletedTask;

View File

@ -162,7 +162,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
public IReadOnlyList<RouteEndpoint> Endpoints { get; set; }
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public override Task MatchAsync(HttpContext httpContext)
{
throw new NotImplementedException();
}

View File

@ -4,6 +4,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Patterns;
using Moq;
@ -21,14 +22,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var scores = new int[] { };
var candidateSet = CreateCandidateSet(endpoints, scores);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
[Fact]
@ -42,14 +43,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[0].Values = new RouteValueDictionary();
candidateSet.SetValidity(0, false);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
[Fact]
@ -63,14 +64,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet[0].Values = new RouteValueDictionary();
candidateSet.SetValidity(0, true);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Same(endpoints[0], context.Endpoint);
Assert.Same(endpoints[0], httpContext.GetEndpoint());
}
[Fact]
@ -84,14 +85,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet.SetValidity(0, false);
candidateSet.SetValidity(1, true);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Same(endpoints[1], context.Endpoint);
Assert.Same(endpoints[1], httpContext.GetEndpoint());
}
[Fact]
@ -106,14 +107,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet.SetValidity(1, true);
candidateSet.SetValidity(2, true);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Same(endpoints[1], context.Endpoint);
Assert.Same(endpoints[1], httpContext.GetEndpoint());
}
[Fact]
@ -137,14 +138,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet.SetValidity(3, false);
candidateSet.SetValidity(4, true);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
await selector.SelectAsync(httpContext, context, candidateSet);
await selector.SelectAsync(httpContext, candidateSet);
// Assert
Assert.Same(endpoints[4], context.Endpoint);
Assert.Same(endpoints[4], httpContext.GetEndpoint());
}
[Fact]
@ -159,23 +160,22 @@ namespace Microsoft.AspNetCore.Routing.Matching
candidateSet.SetValidity(1, true);
candidateSet.SetValidity(2, true);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
var selector = CreateSelector();
// Act
var ex = await Assert.ThrowsAsync<AmbiguousMatchException>(() => selector.SelectAsync(httpContext, context, candidateSet));
var ex = await Assert.ThrowsAsync<AmbiguousMatchException>(() => selector.SelectAsync(httpContext, candidateSet));
// Assert
Assert.Equal(
@"The request matched multiple endpoints. Matches: " + Environment.NewLine + Environment.NewLine +
"test: /test2" + Environment.NewLine + "test: /test3", ex.Message);
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
private static (HttpContext httpContext, EndpointSelectorContext context) CreateContext()
private static HttpContext CreateContext()
{
var httpContext = new DefaultHttpContext();
return (httpContext, new EndpointSelectorContext(httpContext));
return new DefaultHttpContext();
}
private static RouteEndpoint CreateEndpoint(string template)

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
@ -14,13 +14,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
internal override Matcher CreateMatcher(params RouteEndpoint[] endpoints)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Constraints;
using Microsoft.AspNetCore.Routing.Patterns;
@ -76,14 +77,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/1";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.NotNull(context.Endpoint);
Assert.NotNull(httpContext.GetEndpoint());
}
[Fact]
@ -97,14 +98,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/One";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
[Fact]
@ -123,17 +124,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpoint, context.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
Assert.Collection(
context.RouteValues.OrderBy(kvp => kvp.Key),
httpContext.Request.RouteValues.OrderBy(kvp => kvp.Key),
(kvp) =>
{
Assert.Equal("action", kvp.Key);
@ -162,14 +163,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Login/Index";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
[Fact]
@ -188,17 +189,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Home/Index/123";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpoint, context.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
Assert.Collection(
context.RouteValues.OrderBy(kvp => kvp.Key),
httpContext.Request.RouteValues.OrderBy(kvp => kvp.Key),
(kvp) =>
{
Assert.Equal("action", kvp.Key);
@ -237,18 +238,18 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = path;
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpoint, context.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
Assert.Equal("TestAction", context.RouteValues["action"]);
Assert.Equal("TestController", context.RouteValues["controller"]);
Assert.Equal("17", context.RouteValues["id"]);
Assert.Equal("TestAction", httpContext.Request.RouteValues["action"]);
Assert.Equal("TestController", httpContext.Request.RouteValues["controller"]);
Assert.Equal("17", httpContext.Request.RouteValues["id"]);
}
[Fact]
@ -272,22 +273,22 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Home/Index/123";
// Act 1
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert 1
Assert.Same(endpoint1, context.Endpoint);
Assert.Same(endpoint1, httpContext.GetEndpoint());
httpContext.Request.Path = "/Login/Index/123";
// Act 2
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert 2
Assert.Same(endpoint2, context.Endpoint);
Assert.Same(endpoint2, httpContext.GetEndpoint());
}
[Fact]
@ -306,17 +307,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/ConventionalTransformerRoute/conventional-transformer/Index";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpoint, context.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
Assert.Collection(
context.RouteValues.OrderBy(kvp => kvp.Key),
httpContext.Request.RouteValues.OrderBy(kvp => kvp.Key),
(kvp) =>
{
Assert.Equal("action", kvp.Key);
@ -345,17 +346,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/TestController";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpoint, context.Endpoint);
Assert.Same(endpoint, httpContext.GetEndpoint());
Assert.Collection(
context.RouteValues.OrderBy(kvp => kvp.Key),
httpContext.Request.RouteValues.OrderBy(kvp => kvp.Key),
(kvp) =>
{
Assert.Equal("action", kvp.Key);
@ -383,14 +384,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Equal(lowerOrderEndpoint, context.Endpoint);
Assert.Equal(lowerOrderEndpoint, httpContext.GetEndpoint());
}
[Fact]
@ -402,8 +403,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpointSelector = new Mock<EndpointSelector>();
endpointSelector
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, CandidateSet>((c, cs) =>
{
Assert.Equal(2, cs.Count);
@ -417,7 +418,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Assert.Equal(1, cs[1].Score);
Assert.Null(cs[1].Values);
f.Endpoint = endpoint2;
c.SetEndpoint(endpoint2);
})
.Returns(Task.CompletedTask);
@ -429,14 +430,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource, endpointSelector: endpointSelector.Object);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Equal(endpoint2, context.Endpoint);
Assert.Equal(endpoint2, httpContext.GetEndpoint());
}
[Fact]
@ -448,8 +449,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpointSelector = new Mock<EndpointSelector>();
endpointSelector
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, CandidateSet>((c, cs) =>
{
Assert.Equal(2, cs.Count);
@ -463,7 +464,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Assert.Equal(1, cs[1].Score);
Assert.Empty(cs[1].Values);
f.Endpoint = endpoint2;
c.SetEndpoint(endpoint2);
})
.Returns(Task.CompletedTask);
@ -475,14 +476,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource, endpointSelector: endpointSelector.Object);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Equal(endpoint2, context.Endpoint);
Assert.Equal(endpoint2, httpContext.GetEndpoint());
}
[Fact]
@ -495,8 +496,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpointSelector = new Mock<EndpointSelector>();
endpointSelector
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(s => s.SelectAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Callback<HttpContext, CandidateSet>((c, cs) =>
{
Assert.Equal(2, cs.Count);
@ -510,7 +511,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Assert.Equal(1, cs[1].Score);
Assert.Empty(cs[1].Values);
f.Endpoint = endpoint2;
c.SetEndpoint(endpoint2);
})
.Returns(Task.CompletedTask);
@ -522,14 +523,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(endpointDataSource, endpointSelector: endpointSelector.Object);
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/Teams";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Equal(endpoint2, context.Endpoint);
Assert.Equal(endpoint2, httpContext.GetEndpoint());
}
[Fact]
@ -544,14 +545,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var sink = new TestSink();
var matcher = CreateDfaMatcher(endpointDataSource, loggerFactory: new TestLoggerFactory(sink, enabled: true));
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
Assert.Collection(
sink.Writes,
@ -574,14 +575,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var sink = new TestSink();
var matcher = CreateDfaMatcher(endpointDataSource, loggerFactory: new TestLoggerFactory(sink, enabled: true));
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/One";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
Assert.Collection(
sink.Writes,
@ -614,14 +615,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var sink = new TestSink();
var matcher = CreateDfaMatcher(endpointDataSource, loggerFactory: new TestLoggerFactory(sink, enabled: true));
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/One";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
Assert.Collection(
sink.Writes,
@ -656,14 +657,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var sink = new TestSink();
var matcher = CreateDfaMatcher(endpointDataSource, loggerFactory: new TestLoggerFactory(sink, enabled: true));
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/One";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(endpointDataSource.Endpoints[0], context.Endpoint);
Assert.Same(endpointDataSource.Endpoints[0], httpContext.GetEndpoint());
Assert.Collection(
sink.Writes,
@ -716,8 +717,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
.Setup(p => p.AppliesToEndpoints(It.IsAny<IReadOnlyList<Endpoint>>())).Returns(true);
policy
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, CandidateSet>((c, cs) =>
{
cs.SetValidity(1, false);
return Task.CompletedTask;
@ -725,14 +726,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var matcher = CreateDfaMatcher(dataSource, policies: new[] { policy.Object, });
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/test/17";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(dataSource.Endpoints[2], context.Endpoint);
Assert.Same(dataSource.Endpoints[2], httpContext.GetEndpoint());
}
[Fact]
@ -752,22 +753,22 @@ namespace Microsoft.AspNetCore.Routing.Matching
.Setup(p => p.AppliesToEndpoints(It.IsAny<IReadOnlyList<Endpoint>>())).Returns(false);
policy
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, CandidateSet>((c, cs) =>
{
throw null; // Won't be called.
});
var matcher = CreateDfaMatcher(dataSource, policies: new[] { policy.Object, });
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/test/17";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(dataSource.Endpoints[1], context.Endpoint);
Assert.Same(dataSource.Endpoints[1], httpContext.GetEndpoint());
}
[Fact]
@ -787,10 +788,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
.Setup(p => p.AppliesToEndpoints(It.IsAny<IReadOnlyList<Endpoint>>())).Returns(true);
policy1
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, EndpointSelectorContext, CandidateSet>((c, f, cs) =>
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Returns<HttpContext, CandidateSet>((c, cs) =>
{
f.Endpoint = cs[0].Endpoint;
c.SetEndpoint(cs[0].Endpoint);
return Task.CompletedTask;
});
@ -804,26 +805,24 @@ namespace Microsoft.AspNetCore.Routing.Matching
.Setup(p => p.AppliesToEndpoints(It.IsAny<IReadOnlyList<Endpoint>>())).Returns(true);
policy2
.As<IEndpointSelectorPolicy>()
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<EndpointSelectorContext>(), It.IsAny<CandidateSet>()))
.Setup(p => p.ApplyAsync(It.IsAny<HttpContext>(), It.IsAny<CandidateSet>()))
.Throws(new InvalidOperationException());
var matcher = CreateDfaMatcher(dataSource, policies: new[] { policy1.Object, policy2.Object, });
var (httpContext, context) = CreateContext();
var httpContext = CreateContext();
httpContext.Request.Path = "/test/17";
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.Same(dataSource.Endpoints[0], context.Endpoint);
Assert.Same(dataSource.Endpoints[0], httpContext.GetEndpoint());
}
private (HttpContext httpContext, EndpointSelectorContext context) CreateContext()
private HttpContext CreateContext()
{
var httpContext = new DefaultHttpContext();
return (httpContext, new EndpointSelectorContext(httpContext));
return new DefaultHttpContext();
}
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
@ -28,13 +28,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Fact]
@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var endpoint = CreateEndpoint("/a/{b}/{c}", new { b = "17", c = "18", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/a");
var httpContext = CreateContext("/a");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, new { b = "17", c = "18", });
MatcherAssert.AssertMatch(httpContext, endpoint, new { b = "17", c = "18", });
}
[Fact]
@ -58,13 +58,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var endpoint = CreateEndpoint("/a/{b}/{c}", new { b = "17", c = "18", d = "19" });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/a");
var httpContext = CreateContext("/a");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, new { b = "17", c = "18", d = "19" });
MatcherAssert.AssertMatch(httpContext, endpoint, new { b = "17", c = "18", d = "19" });
}
[Theory]
@ -83,13 +83,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Theory]
@ -115,13 +115,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Theory]
@ -138,13 +138,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Theory]
@ -162,13 +162,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
// Historically catchall segments don't match an empty segment, but only if it's
@ -182,13 +182,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
// Need to access these to prevent a warning from the xUnit analyzer.
// Some of these tests will match (and process the values) and some will not.
@ -217,13 +217,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Theory]
@ -237,13 +237,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Theory]
@ -266,13 +266,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Theory]
@ -292,13 +292,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
// Most of are copied from old routing tests that date back to the VS 2010 era. Enjoy!
@ -317,13 +317,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Theory]
@ -347,13 +347,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var matcher = CreateMatcher(other, expected);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(httpContext, expected, ignoreValues: true);
}
[Theory]
@ -381,13 +381,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
// Arrange
var matcher = CreateMatcher(other, expected);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(httpContext, expected, ignoreValues: true);
}
[Theory]
@ -434,13 +434,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var expected = endpoints[Array.IndexOf(templates, expectedTemplate)];
var matcher = CreateMatcher(endpoints);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, expected, ignoreValues: true);
MatcherAssert.AssertMatch(httpContext, expected, ignoreValues: true);
}
}
}
}

View File

@ -24,13 +24,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -40,13 +40,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:8080", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com:8080");
var httpContext = CreateContext("/hello", "contoso.com:8080");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -56,13 +56,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "æon.contoso.com", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "æon.contoso.com");
var httpContext = CreateContext("/hello", "æon.contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -72,13 +72,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:8080", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com:1111");
var httpContext = CreateContext("/hello", "contoso.com:1111");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact]
@ -88,13 +88,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:8080", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "www.contoso.com:8080");
var httpContext = CreateContext("/hello", "www.contoso.com:8080");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact]
@ -104,13 +104,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "æon.contoso.com:8080");
var httpContext = CreateContext("/hello", "æon.contoso.com:8080");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -120,13 +120,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*.contoso.com:8080", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "www.contoso.com:8080");
var httpContext = CreateContext("/hello", "www.contoso.com:8080");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -136,13 +136,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "Contoso.COM", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -152,13 +152,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:80", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com", "http");
var httpContext = CreateContext("/hello", "contoso.com", "http");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -168,13 +168,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:443", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com", "https");
var httpContext = CreateContext("/hello", "contoso.com", "https");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -184,13 +184,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "contoso.com:443", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", null, "https");
var httpContext = CreateContext("/hello", null, "https");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact]
@ -200,13 +200,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*:443", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", null, "https");
var httpContext = CreateContext("/hello", null, "https");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -216,13 +216,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello");
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -232,13 +232,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -248,13 +248,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -264,13 +264,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", hosts: new string[] { "*:*", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "contoso.com");
var httpContext = CreateContext("/hello", "contoso.com");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
private static Matcher CreateMatcher(params RouteEndpoint[] endpoints)
@ -290,7 +290,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return builder.Build();
}
internal static (HttpContext httpContext, EndpointSelectorContext context) CreateContext(
internal static HttpContext CreateContext(
string path,
string host,
string scheme = null)
@ -303,7 +303,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
httpContext.Request.Path = path;
httpContext.Request.Scheme = scheme;
return (httpContext, new EndpointSelectorContext(httpContext));
return httpContext;
}
internal RouteEndpoint CreateEndpoint(

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.Extensions.DependencyInjection;
@ -25,13 +26,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -41,13 +42,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -57,13 +58,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
var httpContext = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
@ -74,14 +75,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GET", }, acceptCorsPreflight: false);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
var httpContext = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.NotSame(endpoint, context.Endpoint);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
Assert.NotSame(endpoint, httpContext.GetEndpoint());
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, httpContext.GetEndpoint().DisplayName);
}
[Fact]
@ -91,13 +92,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GeT", });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -107,13 +108,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { "GeT", }, acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
var httpContext = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -123,13 +124,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello");
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -139,13 +140,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", acceptCorsPreflight: true);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
var httpContext = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact] // This matches because the endpoint accepts OPTIONS
@ -155,13 +156,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", acceptCorsPreflight: false);
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET", corsPreflight: true);
var httpContext = CreateContext("/hello", "GET", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -171,13 +172,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint = CreateEndpoint("/hello", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact] // When all of the candidates handles specific verbs, use a 405 endpoint
@ -188,19 +189,19 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "POST");
var httpContext = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.NotSame(endpoint1, context.Endpoint);
Assert.NotSame(endpoint2, context.Endpoint);
Assert.NotSame(endpoint1, httpContext.GetEndpoint());
Assert.NotSame(endpoint2, httpContext.GetEndpoint());
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, httpContext.GetEndpoint().DisplayName);
// Invoke the endpoint
await context.Endpoint.RequestDelegate(httpContext);
await httpContext.GetEndpoint().RequestDelegate(httpContext);
Assert.Equal(405, httpContext.Response.StatusCode);
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
}
@ -213,13 +214,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "POST", corsPreflight: true);
var httpContext = CreateContext("/hello", "POST", corsPreflight: true);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact] // When one of the candidates handles all verbs, dont use a 405 endpoint
@ -230,13 +231,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "POST");
var httpContext = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact]
@ -247,13 +248,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/bar");
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint1);
MatcherAssert.AssertMatch(httpContext, endpoint1);
}
[Fact]
@ -264,13 +265,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/bar", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "GET");
var httpContext = CreateContext("/hello", "GET");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint1);
MatcherAssert.AssertMatch(httpContext, endpoint1);
}
[Fact] // The non-http-method-specific endpoint is part of the same candidate set
@ -281,13 +282,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/{x}", httpMethods: new string[] { });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "POST");
var httpContext = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint2, ignoreValues: true);
MatcherAssert.AssertMatch(httpContext, endpoint2, ignoreValues: true);
}
[Fact] // See https://github.com/aspnet/AspNetCore/issues/6415
@ -298,24 +299,24 @@ namespace Microsoft.AspNetCore.Routing.Matching
var endpoint2 = CreateEndpoint("/hello", httpMethods: new string[] { "DELETE" });
var matcher = CreateMatcher(endpoint1, endpoint2);
var (httpContext, context) = CreateContext("/hello", "POST");
var httpContext = CreateContext("/hello", "POST");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
Assert.NotSame(endpoint1, context.Endpoint);
Assert.NotSame(endpoint2, context.Endpoint);
Assert.NotSame(endpoint1, httpContext.GetEndpoint());
Assert.NotSame(endpoint2, httpContext.GetEndpoint());
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, context.Endpoint.DisplayName);
Assert.Same(HttpMethodMatcherPolicy.Http405EndpointDisplayName, httpContext.GetEndpoint().DisplayName);
// Invoke the endpoint
await context.Endpoint.RequestDelegate(httpContext);
await httpContext.GetEndpoint().RequestDelegate(httpContext);
Assert.Equal(405, httpContext.Response.StatusCode);
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
// Invoke the endpoint again to verify headers not duplicated
await context.Endpoint.RequestDelegate(httpContext);
await httpContext.GetEndpoint().RequestDelegate(httpContext);
Assert.Equal(405, httpContext.Response.StatusCode);
Assert.Equal("DELETE, GET, PUT", httpContext.Response.Headers["Allow"]);
}
@ -337,7 +338,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return builder.Build();
}
internal static (HttpContext httpContext, EndpointSelectorContext context) CreateContext(
internal static HttpContext CreateContext(
string path,
string httpMethod,
bool corsPreflight = false)
@ -352,7 +353,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
httpContext.Request.Headers[AccessControlRequestMethod] = httpMethod;
}
return (httpContext, new EndpointSelectorContext(httpContext));
return httpContext;
}
internal RouteEndpoint CreateEndpoint(

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Xunit.Sdk;
@ -27,22 +28,22 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
}
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected)
public static void AssertMatch(HttpContext httpContext, Endpoint expected)
{
AssertMatch(context, httpContext, expected, new RouteValueDictionary());
AssertMatch(httpContext, expected, new RouteValueDictionary());
}
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, bool ignoreValues)
public static void AssertMatch(HttpContext httpContext, Endpoint expected, bool ignoreValues)
{
AssertMatch(context, httpContext, expected, new RouteValueDictionary(), ignoreValues);
AssertMatch(httpContext, expected, new RouteValueDictionary(), ignoreValues);
}
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, object values)
public static void AssertMatch(HttpContext httpContext, Endpoint expected, object values)
{
AssertMatch(context, httpContext, expected, new RouteValueDictionary(values));
AssertMatch(httpContext, expected, new RouteValueDictionary(values));
}
public static void AssertMatch(EndpointSelectorContext context, HttpContext httpContext, Endpoint expected, string[] keys, string[] values)
public static void AssertMatch(HttpContext httpContext, Endpoint expected, string[] keys, string[] values)
{
keys = keys ?? Array.Empty<string>();
values = values ?? Array.Empty<string>();
@ -53,17 +54,16 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
var zipped = keys.Zip(values, (k, v) => new KeyValuePair<string, object>(k, v));
AssertMatch(context, httpContext, expected, new RouteValueDictionary(zipped));
AssertMatch(httpContext, expected, new RouteValueDictionary(zipped));
}
public static void AssertMatch(
EndpointSelectorContext context,
HttpContext httpContext,
Endpoint expected,
RouteValueDictionary values,
bool ignoreValues = false)
{
if (context.Endpoint == null)
if (httpContext.GetEndpoint() == null)
{
throw new XunitException($"Was expected to match '{expected.DisplayName}' but did not match.");
}
@ -75,11 +75,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
throw new XunitException("RouteValues is null.");
}
if (!object.ReferenceEquals(expected, context.Endpoint))
if (!object.ReferenceEquals(expected, httpContext.GetEndpoint()))
{
throw new XunitException(
$"Was expected to match '{expected.DisplayName}' but matched " +
$"'{context.Endpoint.DisplayName}' with values: {FormatRouteValues(actualValues)}.");
$"'{httpContext.GetEndpoint().DisplayName}' with values: {FormatRouteValues(actualValues)}.");
}
if (!ignoreValues)
@ -96,13 +96,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
}
}
public static void AssertNotMatch(EndpointSelectorContext context, HttpContext httpContext)
public static void AssertNotMatch(HttpContext httpContext)
{
if (context.Endpoint != null)
if (httpContext.GetEndpoint() != null)
{
throw new XunitException(
$"Was expected not to match '{context.Endpoint.DisplayName}' " +
$"but matched with values: {FormatRouteValues(httpContext.Features.Get<IRouteValuesFeature>().RouteValues)}.");
$"Was expected not to match '{httpContext.GetEndpoint().DisplayName}' " +
$"but matched with values: {FormatRouteValues(httpContext.Request.RouteValues)}.");
}
}

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
@ -13,13 +13,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/");
var (httpContext, context) = CreateContext("/");
var httpContext = CreateContext("/");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -27,13 +27,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, context) = CreateContext("/simple");
var httpContext = CreateContext("/simple");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Fact]
@ -41,13 +41,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, context) = CreateContext("/simple/");
var httpContext = CreateContext("/simple/");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Theory]
@ -58,13 +58,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/Simple");
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
// Some matchers will optimize for the ASCII case
@ -75,13 +75,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
// Matchers should operate on the decoded representation - a matcher that calls
@ -93,13 +93,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
[Theory]
@ -113,13 +113,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/simple");
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Theory]
@ -130,13 +130,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext("/simple");
var httpContext = CreateContext("/simple");
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
// Matchers do their own 'splitting' of the path into segments, so including
@ -153,13 +153,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint);
MatcherAssert.AssertMatch(httpContext, endpoint);
}
// Matchers do their own 'splitting' of the path into segments, so including
@ -184,13 +184,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Fact]
@ -198,14 +198,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, context) = CreateContext("/14");
var httpContext = CreateContext("/14");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
MatcherAssert.AssertMatch(httpContext, endpoint, values);
}
[Fact]
@ -213,14 +213,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p:int}");
var (httpContext, context) = CreateContext("/14");
var httpContext = CreateContext("/14");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
MatcherAssert.AssertMatch(httpContext, endpoint, values);
}
[Fact]
@ -228,14 +228,14 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, context) = CreateContext("/14/");
var httpContext = CreateContext("/14/");
var values = new RouteValueDictionary(new { p = "14", });
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
MatcherAssert.AssertMatch(httpContext, endpoint, values);
}
[Fact]
@ -243,7 +243,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/foo/{ }/{.!$%}/{dynamic.data}");
var (httpContext, context) = CreateContext("/foo/space/weirdmatch/matcherid");
var httpContext = CreateContext("/foo/space/weirdmatch/matcherid");
var values = new RouteValueDictionary()
{
{ " ", "space" },
@ -252,10 +252,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
};
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, values);
MatcherAssert.AssertMatch(httpContext, endpoint, values);
}
[Theory]
@ -267,13 +267,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher("/{p}");
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
[Theory]
@ -288,13 +288,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertMatch(context, httpContext, endpoint, keys, values);
MatcherAssert.AssertMatch(httpContext, endpoint, keys, values);
}
[Theory]
@ -317,13 +317,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
// Arrange
var (matcher, endpoint) = CreateMatcher(template);
var (httpContext, context) = CreateContext(path);
var httpContext = CreateContext(path);
// Act
await matcher.MatchAsync(httpContext, context);
await matcher.MatchAsync(httpContext);
// Assert
MatcherAssert.AssertNotMatch(context, httpContext);
MatcherAssert.AssertNotMatch(httpContext);
}
}
}

View File

@ -14,13 +14,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
{
internal abstract Matcher CreateMatcher(params RouteEndpoint[] endpoints);
internal static (HttpContext httpContext, EndpointSelectorContext context) CreateContext(string path)
internal static HttpContext CreateContext(string path)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.Method = "TEST";
httpContext.Request.Path = path;
httpContext.RequestServices = CreateServices();
return (httpContext, new EndpointSelectorContext(httpContext));
return httpContext;
}
// The older routing implementations retrieve services when they first execute.

View File

@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_inner = inner;
}
public async override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public async override Task MatchAsync(HttpContext httpContext)
{
if (httpContext == null)
{
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (routeContext.Handler != null)
{
context.RouteValues = routeContext.RouteData.Values;
httpContext.Request.RouteValues = routeContext.RouteData.Values;
await routeContext.Handler(httpContext);
}
}

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Patterns;
using Microsoft.AspNetCore.Routing.TestObjects;
@ -96,13 +97,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
public async Task RouteAsync(RouteContext routeContext)
{
var context = new EndpointSelectorContext(routeContext.HttpContext);
// This is needed due to a quirk of our tests - they reuse the endpoint feature.
context.Endpoint = null;
routeContext.HttpContext.SetEndpoint(null);
await _selector.SelectAsync(routeContext.HttpContext, context, new CandidateSet(_candidates, _values, _scores));
if (context.Endpoint != null)
await _selector.SelectAsync(routeContext.HttpContext, new CandidateSet(_candidates, _values, _scores));
if (routeContext.HttpContext.GetEndpoint() != null)
{
routeContext.Handler = (_) => Task.CompletedTask;
}

View File

@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
_inner = inner;
}
public async override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public async override Task MatchAsync(HttpContext httpContext)
{
if (httpContext == null)
{
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (routeContext.Handler != null)
{
context.RouteValues = routeContext.RouteData.Values;
httpContext.Request.RouteValues = routeContext.RouteData.Values;
await routeContext.Handler(httpContext);
}
}

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Internal;
using Microsoft.AspNetCore.Routing.Template;
@ -99,13 +100,11 @@ namespace Microsoft.AspNetCore.Routing.Matching
public async Task RouteAsync(RouteContext routeContext)
{
var context = new EndpointSelectorContext(routeContext.HttpContext);
// This is needed due to a quirk of our tests - they reuse the endpoint feature.
context.Endpoint = null;
routeContext.HttpContext.SetEndpoint(null);
await _selector.SelectAsync(routeContext.HttpContext, context, new CandidateSet(_candidates, _values, _scores));
if (context.Endpoint != null)
await _selector.SelectAsync(routeContext.HttpContext, new CandidateSet(_candidates, _values, _scores));
if (routeContext.HttpContext.GetEndpoint() != null)
{
routeContext.Handler = (_) => Task.CompletedTask;
}

View File

@ -1,8 +1,9 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Matching;
@ -17,12 +18,12 @@ namespace Microsoft.AspNetCore.Routing.TestObjects
_isHandled = isHandled;
}
public override Task MatchAsync(HttpContext httpContext, EndpointSelectorContext context)
public override Task MatchAsync(HttpContext httpContext)
{
if (_isHandled)
{
context.RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index" });
context.Endpoint = new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "Test endpoint");
httpContext.Request.RouteValues = new RouteValueDictionary(new { controller = "Home", action = "Index" });
httpContext.SetEndpoint(new Endpoint(TestConstants.EmptyRequestDelegate, EndpointMetadataCollection.Empty, "Test endpoint"));
}
return Task.CompletedTask;

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
if (action?.ActionConstraints?.Count > 0 && HasSignificantActionConstraint(action))
{
// We need to check for some specific action constraint implementations.
// We've implemented consumes, and HTTP method support inside endpoint routing, so
// We've implemented consumes, and HTTP method support inside endpoint routing, so
// we don't need to run an 'action constraint phase' if those are the only constraints.
return true;
}
@ -81,7 +81,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
}
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidateSet)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidateSet)
{
var finalMatches = EvaluateActionConstraints(httpContext, candidateSet);

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matching;
@ -53,7 +54,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return endpoints.Any(e => e.Metadata.GetMetadata<IConsumesMetadata>()?.ContentTypes.Count > 0);
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{
@ -106,7 +107,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
}
var contentType = httpContext.Request.ContentType;
var mediaType = string.IsNullOrEmpty(contentType) ? (MediaType?)null : new MediaType(contentType);
var mediaType = string.IsNullOrEmpty(contentType) ? (MediaType?)null : new MediaType(contentType);
var matched = false;
for (var j = 0; j < metadata.ContentTypes.Count; j++)
@ -145,7 +146,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
if (needs415Endpoint == true)
{
// We saw some endpoints coming in, and we eliminated them all.
context.Endpoint = CreateRejectionEndpoint();
httpContext.SetEndpoint(CreateRejectionEndpoint());
}
return Task.CompletedTask;
@ -220,7 +221,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var mediaType = new MediaType(contentType);
// Example: 'application/json' is subset of 'application/*'
//
//
// This means that when the request has content-type 'application/json' an endpoint
// what consumes 'application/*' should match.
if (edgeKey.IsSubsetOf(mediaType))

View File

@ -60,13 +60,13 @@ namespace Microsoft.AspNetCore.Mvc.Routing
return false;
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{
throw new ArgumentNullException(nameof(httpContext));
}
if (candidates == null)
{
throw new ArgumentNullException(nameof(candidates));
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
// If there's no match this is a configuration error. We can't really check
// during startup that the action you configured exists.
throw new InvalidOperationException(
"Cannot find the fallback endpoint specified by route values: " +
"Cannot find the fallback endpoint specified by route values: " +
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
}

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Endpoints;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matching;
using Microsoft.AspNetCore.Routing.Patterns;
@ -326,13 +327,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -348,13 +348,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -370,13 +369,12 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext();
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -392,7 +390,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext()
{
Request =
@ -404,7 +401,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -420,7 +417,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext()
{
Request =
@ -432,7 +428,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -448,7 +444,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext()
{
Request =
@ -460,7 +455,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -476,7 +471,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext()
{
Request =
@ -488,7 +482,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -504,7 +498,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
};
var candidates = CreateCandidateSet(endpoints);
var context = new EndpointSelectorContext();
var httpContext = new DefaultHttpContext()
{
Request =
@ -516,7 +509,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.True(candidates.IsValidCandidate(0));
@ -539,16 +532,15 @@ namespace Microsoft.AspNetCore.Mvc.Routing
ContentType = "application/json",
},
};
var context = new EndpointSelectorContext(httpContext);
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.False(candidates.IsValidCandidate(0));
Assert.NotNull(context.Endpoint);
Assert.NotNull(httpContext.GetEndpoint());
}
[Fact]
@ -569,16 +561,15 @@ namespace Microsoft.AspNetCore.Mvc.Routing
ContentType = "application/json",
},
};
var context = new EndpointSelectorContext(httpContext);
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.False(candidates.IsValidCandidate(0));
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
[Fact]
@ -599,17 +590,16 @@ namespace Microsoft.AspNetCore.Mvc.Routing
ContentType = "application/json",
},
};
var context = new EndpointSelectorContext(httpContext);
var policy = CreatePolicy();
// Act
await policy.ApplyAsync(httpContext, context, candidates);
await policy.ApplyAsync(httpContext, candidates);
// Assert
Assert.False(candidates.IsValidCandidate(0));
Assert.True(candidates.IsValidCandidate(1));
Assert.Null(context.Endpoint);
Assert.Null(httpContext.GetEndpoint());
}
private static RouteEndpoint CreateEndpoint(string template, ConsumesMetadata consumesMetadata, params object[] more)

View File

@ -61,7 +61,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
return false;
}
public async Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public async Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
// If there's no match this is a configuration error. We can't really check
// during startup that the action you configured exists.
throw new InvalidOperationException(
"Cannot find the fallback endpoint specified by route values: " +
"Cannot find the fallback endpoint specified by route values: " +
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
}
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
var compiled = await _loader.LoadAsync(endpoints[0].Metadata.GetMetadata<PageActionDescriptor>());
var replacement = compiled.Endpoint;
// We need to provide the route values associated with this endpoint, so that features
// like URL generation work.
var values = new RouteValueDictionary(metadata.Values);

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
return false;
}
public Task ApplyAsync(HttpContext httpContext, EndpointSelectorContext context, CandidateSet candidates)
public Task ApplyAsync(HttpContext httpContext, CandidateSet candidates)
{
if (httpContext == null)
{

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
var policy = new PageLoaderMatcherPolicy(loader);
// Act
await policy.ApplyAsync(new DefaultHttpContext(), new EndpointSelectorContext(), candidateSet);
await policy.ApplyAsync(new DefaultHttpContext(), candidateSet);
// Assert
Assert.Same(compiled.Endpoint, candidateSet[0].Endpoint);
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
var policy = new PageLoaderMatcherPolicy(loader);
// Act
var applyTask = policy.ApplyAsync(new DefaultHttpContext(), new EndpointSelectorContext(), candidateSet);
var applyTask = policy.ApplyAsync(new DefaultHttpContext(), candidateSet);
tcs.SetResult(0);
await applyTask;

View File

@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var selector = CreateSelector(actions);
// Act
await selector.ApplyAsync(new DefaultHttpContext(), new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(new DefaultHttpContext(), candidateSet);
// Assert
Assert.True(candidateSet.IsValidCandidate(0));
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.True(candidateSet.IsValidCandidate(0));
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.False(candidateSet.IsValidCandidate(0));
@ -138,7 +138,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.False(candidateSet.IsValidCandidate(0));
@ -173,7 +173,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.True(candidateSet.IsValidCandidate(0));
@ -211,7 +211,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.False(candidateSet.IsValidCandidate(0));
@ -246,7 +246,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.False(candidateSet.IsValidCandidate(0));
@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.True(candidateSet.IsValidCandidate(0));
@ -328,7 +328,7 @@ namespace Microsoft.AspNetCore.Mvc.Routing
var httpContext = CreateHttpContext("POST");
// Act
await selector.ApplyAsync(httpContext, new EndpointSelectorContext(), candidateSet);
await selector.ApplyAsync(httpContext, candidateSet);
// Assert
Assert.True(candidateSet.IsValidCandidate(0));