Allow fallback to controller to use MatcherPolicy
This commit is contained in:
parent
4f015e2813
commit
6f305373ca
|
|
@ -14,15 +14,22 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
internal class DynamicControllerEndpointMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
internal class DynamicControllerEndpointMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
||||||
{
|
{
|
||||||
private readonly DynamicControllerEndpointSelector _selector;
|
private readonly DynamicControllerEndpointSelector _selector;
|
||||||
|
private readonly EndpointMetadataComparer _comparer;
|
||||||
|
|
||||||
public DynamicControllerEndpointMatcherPolicy(DynamicControllerEndpointSelector selector)
|
public DynamicControllerEndpointMatcherPolicy(DynamicControllerEndpointSelector selector, EndpointMetadataComparer comparer)
|
||||||
{
|
{
|
||||||
if (selector == null)
|
if (selector == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(selector));
|
throw new ArgumentNullException(nameof(selector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (comparer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(comparer));
|
||||||
|
}
|
||||||
|
|
||||||
_selector = selector;
|
_selector = selector;
|
||||||
|
_comparer = comparer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Order => int.MinValue + 100;
|
public override int Order => int.MinValue + 100;
|
||||||
|
|
@ -99,8 +106,6 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
|
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var replacement = endpoints[0];
|
|
||||||
|
|
||||||
// We need to provide the route values associated with this endpoint, so that features
|
// We need to provide the route values associated with this endpoint, so that features
|
||||||
// like URL generation work.
|
// like URL generation work.
|
||||||
var values = new RouteValueDictionary(metadata.Values);
|
var values = new RouteValueDictionary(metadata.Values);
|
||||||
|
|
@ -111,7 +116,11 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
||||||
values.TryAdd(kvp.Key, kvp.Value);
|
values.TryAdd(kvp.Key, kvp.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
candidates.ReplaceEndpoint(i, replacement, values);
|
// Update the route values
|
||||||
|
candidates.ReplaceEndpoint(i, endpoint, values);
|
||||||
|
|
||||||
|
// Expand the list of endpoints
|
||||||
|
candidates.ExpandEndpoint(i, endpoints, _comparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
|
@ -106,6 +107,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
|
"{ " + string.Join(", ", metadata.Values.Select(kvp => $"{kvp.Key}: {kvp.Value}")) + " }.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// It should not be possible to have more than one result for pages.
|
||||||
|
Debug.Assert(endpoints.Count == 1);
|
||||||
|
|
||||||
var compiled = await _loader.LoadAsync(endpoints[0].Metadata.GetMetadata<PageActionDescriptor>());
|
var compiled = await _loader.LoadAsync(endpoints[0].Metadata.GetMetadata<PageActionDescriptor>());
|
||||||
var replacement = compiled.Endpoint;
|
var replacement = compiled.Endpoint;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,22 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.Equal("Hello from fallback controller: /Admin/Fallback", content);
|
Assert.Equal("Hello from fallback controller: /Admin/Fallback", content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Fallback_CanFallbackToControllerInAreaPost()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var url = "http://localhost/Admin/Foo";
|
||||||
|
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var response = await Client.SendAsync(request);
|
||||||
|
var content = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal("Hello from fallback controller POST: /Admin/Fallback", content);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Fallback_CanFallbackToPage()
|
public async Task Fallback_CanFallbackToPage()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -12,5 +12,11 @@ namespace RoutingWebSite.Areas.Admin
|
||||||
{
|
{
|
||||||
return Content("Hello from fallback controller: " + Url.Action());
|
return Content("Hello from fallback controller: " + Url.Action());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public ActionResult Index(int x)
|
||||||
|
{
|
||||||
|
return Content("Hello from fallback controller POST: " + Url.Action());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue