diff --git a/build/dependencies.props b/build/dependencies.props index 889ffe96a4..6b40e23716 100644 --- a/build/dependencies.props +++ b/build/dependencies.props @@ -16,87 +16,87 @@ 0.42.1 2.1.0 2.1.0-rc1-final - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 2.2.0-preview1-17099 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 5.2.6 2.8.0 2.8.0 - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 1.7.0 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 2.1.0 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 2.0.9 2.1.2 2.2.0-preview1-26618-02 - 2.2.0-preview1-34773 - 2.2.0-preview1-34773 + 2.2.0-preview1-34781 + 2.2.0-preview1-34781 15.6.1 4.7.49 2.0.3 diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/GlobalRoutingTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/GlobalRoutingTest.cs index a95147250d..574b7f8160 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/GlobalRoutingTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/GlobalRoutingTest.cs @@ -3,6 +3,7 @@ using System; using System.Net; +using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; using Xunit; @@ -76,5 +77,88 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests Array.Empty(), result.Routers); } + + // Global routing exposes HTTP 405s for HTTP method mismatches + [Fact] + public override async Task ConventionalRoutedController_InArea_ActionBlockedByHttpMethod() + { + // Arrange & Act + var response = await Client.GetAsync("http://localhost/Travel/Flight/BuyTickets"); + + // Assert + Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); + } + + // Global routing exposes HTTP 405s for HTTP method mismatches + [Fact] + public override async Task AttributeRoutedAction_MultipleRouteAttributes_RouteAttributeTemplatesIgnoredForOverrideActions() + { + // Arrange + var url = "http://localhost/api/v1/Maps"; + + // Act + var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod("POST"), url)); + + // Assert + Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); + } + + // Global routing exposes HTTP 405s for HTTP method mismatches + [Theory] + [InlineData("http://localhost/api/v1/Maps/5", "PATCH")] + [InlineData("http://localhost/api/v2/Maps/5", "PATCH")] + [InlineData("http://localhost/api/v1/Maps/PartialUpdate/5", "PUT")] + [InlineData("http://localhost/api/v2/Maps/PartialUpdate/5", "PUT")] + public override async Task AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraints( + string url, + string method) + { + // Arrange + var expectedUrl = new Uri(url).AbsolutePath; + + // Act + var response = await Client.SendAsync(new HttpRequestMessage(new HttpMethod(method), url)); + + // Assert + Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); + } + + // Global routing exposes HTTP 405s for HTTP method mismatches + [Theory] + [InlineData("Post", "/Friends")] + [InlineData("Put", "/Friends")] + [InlineData("Patch", "/Friends")] + [InlineData("Options", "/Friends")] + [InlineData("Head", "/Friends")] + public override async Task AttributeRoutedAction_RejectsRequestsWithWrongMethods_InRoutesWithoutExtraTemplateSegmentsOnTheAction( + string method, + string url) + { + // Arrange + var request = new HttpRequestMessage(new HttpMethod(method), $"http://localhost{url}"); + + // Assert + var response = await Client.SendAsync(request); + + // Assert + Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); + } + + // These verbs don't match + [Theory] + [InlineData("/Bank/Deposit", "GET")] + [InlineData("/Bank/Deposit/5", "DELETE")] + [InlineData("/Bank/Withdraw/5", "GET")] + public override async Task AttributeRouting_MixedAcceptVerbsAndRoute_Unreachable(string path, string verb) + { + // Arrange + var request = new HttpRequestMessage(new HttpMethod(verb), "http://localhost" + path); + + // Act + var response = await Client.SendAsync(request); + + // Assert + Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RoutingTestsBase.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RoutingTestsBase.cs index f707655dce..a3d236d318 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RoutingTestsBase.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RoutingTestsBase.cs @@ -254,7 +254,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [InlineData("Patch", "/Friends")] [InlineData("Options", "/Friends")] [InlineData("Head", "/Friends")] - public async Task AttributeRoutedAction_RejectsRequestsWithWrongMethods_InRoutesWithoutExtraTemplateSegmentsOnTheAction( + public virtual async Task AttributeRoutedAction_RejectsRequestsWithWrongMethods_InRoutesWithoutExtraTemplateSegmentsOnTheAction( string method, string url) { @@ -321,7 +321,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests } [Fact] - public async Task AttributeRoutedAction_MultipleRouteAttributes_RouteAttributeTemplatesIgnoredForOverrideActions() + public virtual async Task AttributeRoutedAction_MultipleRouteAttributes_RouteAttributeTemplatesIgnoredForOverrideActions() { // Arrange var url = "http://localhost/api/v1/Maps"; @@ -395,7 +395,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [InlineData("http://localhost/api/v2/Maps/5", "PATCH")] [InlineData("http://localhost/api/v1/Maps/PartialUpdate/5", "PUT")] [InlineData("http://localhost/api/v2/Maps/PartialUpdate/5", "PUT")] - public async Task AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraints( + public virtual async Task AttributeRoutedAction_MultipleRouteAttributes_WithMultipleHttpAttributes_RespectsConstraints( string url, string method) { @@ -1212,7 +1212,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests [InlineData("/Bank/Deposit", "GET")] [InlineData("/Bank/Deposit/5", "DELETE")] [InlineData("/Bank/Withdraw/5", "GET")] - public async Task AttributeRouting_MixedAcceptVerbsAndRoute_Unreachable(string path, string verb) + public virtual async Task AttributeRouting_MixedAcceptVerbsAndRoute_Unreachable(string path, string verb) { // Arrange var request = new HttpRequestMessage(new HttpMethod(verb), "http://localhost" + path);