Merge branch 'merge/release/2.2-to-master'
This commit is contained in:
commit
4e915b4ac9
|
|
@ -51,6 +51,20 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="RouteData"/> instance with the specified values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="values">The <see cref="RouteValueDictionary"/> values.</param>
|
||||||
|
public RouteData(RouteValueDictionary values)
|
||||||
|
{
|
||||||
|
if (values == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
_values = values;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the data tokens produced by routes on the current routing path.
|
/// Gets the data tokens produced by routes on the current routing path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -84,7 +98,7 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the set of values produced by routes on the current routing path.
|
/// Gets the values produced by routes on the current routing path.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public RouteValueDictionary Values
|
public RouteValueDictionary Values
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,9 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
var feature = new EndpointFeature();
|
var feature = new EndpointFeature();
|
||||||
httpContext.Features.Set<IEndpointFeature>(feature);
|
httpContext.Features.Set<IEndpointFeature>(feature);
|
||||||
|
|
||||||
|
// Back compat support for users of IRoutingFeature
|
||||||
|
httpContext.Features.Set<IRoutingFeature>(feature);
|
||||||
|
|
||||||
// There's an inherent race condition between waiting for init and accessing the matcher
|
// There's an inherent race condition between waiting for init and accessing the matcher
|
||||||
// this is OK because once `_matcher` is initialized, it will not be set to null again.
|
// this is OK because once `_matcher` is initialized, it will not be set to null again.
|
||||||
var matcher = await InitializeAsync();
|
var matcher = await InitializeAsync();
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,39 @@ using Microsoft.AspNetCore.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Routing
|
namespace Microsoft.AspNetCore.Routing
|
||||||
{
|
{
|
||||||
public sealed class EndpointFeature : IEndpointFeature
|
public sealed class EndpointFeature : IEndpointFeature, IRoutingFeature
|
||||||
{
|
{
|
||||||
|
private RouteData _routeData;
|
||||||
|
private RouteValueDictionary _values;
|
||||||
|
|
||||||
public Endpoint Endpoint { get; set; }
|
public Endpoint Endpoint { get; set; }
|
||||||
|
|
||||||
public Func<RequestDelegate, RequestDelegate> Invoker { get; set; }
|
public Func<RequestDelegate, RequestDelegate> Invoker { get; set; }
|
||||||
|
|
||||||
public RouteValueDictionary Values { get; set; }
|
public RouteValueDictionary Values
|
||||||
|
{
|
||||||
|
get => _values;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_values = value;
|
||||||
|
|
||||||
|
// RouteData will be created next get with new Values
|
||||||
|
_routeData = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RouteData IRoutingFeature.RouteData
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_routeData == null)
|
||||||
|
{
|
||||||
|
_routeData = new RouteData(_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _routeData;
|
||||||
|
}
|
||||||
|
set => throw new NotSupportedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,30 @@ namespace Microsoft.AspNetCore.Routing
|
||||||
Assert.Equal(expectedMessage, write.State?.ToString());
|
Assert.Equal(expectedMessage, write.State?.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Invoke_BackCompatGetRouteValue_ValueUsedFromEndpointFeature()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var httpContext = new DefaultHttpContext();
|
||||||
|
httpContext.RequestServices = new TestServiceProvider();
|
||||||
|
|
||||||
|
var middleware = CreateMiddleware();
|
||||||
|
|
||||||
|
// Act
|
||||||
|
await middleware.Invoke(httpContext);
|
||||||
|
var routeData = httpContext.GetRouteData();
|
||||||
|
var routeValue = httpContext.GetRouteValue("controller");
|
||||||
|
var endpointFeature = httpContext.Features.Get<IEndpointFeature>();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.NotNull(routeData);
|
||||||
|
Assert.Equal("Home", (string)routeValue);
|
||||||
|
|
||||||
|
// changing route data value is reflected in endpoint feature values
|
||||||
|
routeData.Values["testKey"] = "testValue";
|
||||||
|
Assert.Equal("testValue", endpointFeature.Values["testKey"]);
|
||||||
|
}
|
||||||
|
|
||||||
private DispatcherMiddleware CreateMiddleware(Logger<DispatcherMiddleware> logger = null)
|
private DispatcherMiddleware CreateMiddleware(Logger<DispatcherMiddleware> logger = null)
|
||||||
{
|
{
|
||||||
RequestDelegate next = (c) => Task.FromResult<object>(null);
|
RequestDelegate next = (c) => Task.FromResult<object>(null);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ namespace Microsoft.AspNetCore.Routing.TestObjects
|
||||||
{
|
{
|
||||||
if (_isHandled)
|
if (_isHandled)
|
||||||
{
|
{
|
||||||
|
feature.Values = new RouteValueDictionary(new { controller = "Home", action = "Index" });
|
||||||
feature.Endpoint = new TestEndpoint(EndpointMetadataCollection.Empty, "Test endpoint");
|
feature.Endpoint = new TestEndpoint(EndpointMetadataCollection.Empty, "Test endpoint");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue