From 7b9e6c96a7fad045be66bc7f41e48b53e65542dd Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 6 Jun 2025 14:09:31 +0200 Subject: [PATCH 1/2] Add tests for forms under a route with re-execution middleware. --- .../FormWithParentBindingContextTest.cs | 44 +++++++++++++++++++ .../Pages/Forms/DefaultForm.razor | 1 + .../Pages/Forms/FormNoAntiforgery.razor | 1 + .../Pages/Forms/FormNoHandler.razor | 1 + 4 files changed, 47 insertions(+) diff --git a/src/Components/test/E2ETest/ServerRenderingTests/FormHandlingTests/FormWithParentBindingContextTest.cs b/src/Components/test/E2ETest/ServerRenderingTests/FormHandlingTests/FormWithParentBindingContextTest.cs index 3da563d5bc8c..dce828fcefbf 100644 --- a/src/Components/test/E2ETest/ServerRenderingTests/FormHandlingTests/FormWithParentBindingContextTest.cs +++ b/src/Components/test/E2ETest/ServerRenderingTests/FormHandlingTests/FormWithParentBindingContextTest.cs @@ -49,6 +49,20 @@ public void CanDispatchToTheDefaultForm(bool suppressEnhancedNavigation) DispatchToFormCore(dispatchToForm); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void CanDispatchToTheDefaultFormWithReExecutionMiddleware(bool suppressEnhancedNavigation) + { + var dispatchToForm = new DispatchToForm(this) + { + Url = "reexecution/forms/default-form", + FormCssSelector = "form", + SuppressEnhancedNavigation = suppressEnhancedNavigation, + }; + DispatchToFormCore(dispatchToForm); + } + [Fact] public void PlainFormIsNotEnhancedByDefault() { @@ -891,6 +905,21 @@ public async Task CanModifyTheHttpResponseDuringEventHandling() Assert.Equal("ModifyHttpContext", cookie.Value); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void FormNoAntiforgeryReturnBadRequestWithReExecutionMiddleware(bool suppressEnhancedNavigation) + { + var dispatchToForm = new DispatchToForm(this) + { + Url = "reexecution/forms/no-antiforgery", + FormCssSelector = "form", + ShouldCauseBadRequest = true, + SuppressEnhancedNavigation = suppressEnhancedNavigation, + }; + DispatchToFormCore(dispatchToForm); + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -973,6 +1002,21 @@ public void FormNoHandlerReturnBadRequest(bool suppressEnhancedNavigation) DispatchToFormCore(dispatchToForm); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void FormNoHandlerReturnBadRequestWithReExecutionMiddleware(bool suppressEnhancedNavigation) + { + var dispatchToForm = new DispatchToForm(this) + { + Url = "reexecution/forms/no-handler", + FormCssSelector = "form", + ShouldCauseBadRequest = true, + SuppressEnhancedNavigation = suppressEnhancedNavigation, + }; + DispatchToFormCore(dispatchToForm); + } + [Theory] [InlineData(true)] [InlineData(false)] diff --git a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/DefaultForm.razor b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/DefaultForm.razor index e33200a8a5a5..54c25fd1dbc8 100644 --- a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/DefaultForm.razor +++ b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/DefaultForm.razor @@ -1,4 +1,5 @@ @page "/forms/default-form" +@page "/reexecution/forms/default-form" @using Microsoft.AspNetCore.Components.Forms

Default form

diff --git a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoAntiforgery.razor b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoAntiforgery.razor index 5ab564216a9d..93991bab3279 100644 --- a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoAntiforgery.razor +++ b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoAntiforgery.razor @@ -1,4 +1,5 @@ @page "/forms/no-antiforgery" +@page "/reexecution/forms/no-antiforgery" @using Microsoft.AspNetCore.Components.Forms

Default form

diff --git a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoHandler.razor b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoHandler.razor index 9bce527bb582..6ec5170a5928 100644 --- a/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoHandler.razor +++ b/src/Components/test/testassets/Components.TestServer/RazorComponents/Pages/Forms/FormNoHandler.razor @@ -1,4 +1,5 @@ @page "/forms/no-handler" +@page "/reexecution/forms/no-handler" @using Microsoft.AspNetCore.Components.Forms

Form with no handler

From a37ec81c7db4a6c9f1aea39bf085f1775d2f4c27 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz Date: Fri, 6 Jun 2025 14:10:10 +0200 Subject: [PATCH 2/2] Fix - treat POST as POST, even when re-execution middleware is set. --- .../Endpoints/src/RazorComponentEndpointInvoker.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs index 245f811d7f76..c357d5ea2d80 100644 --- a/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs +++ b/src/Components/Endpoints/src/RazorComponentEndpointInvoker.cs @@ -175,11 +175,10 @@ await _renderer.InitializeStandardComponentServicesAsync( private async Task ValidateRequestAsync(HttpContext context, IAntiforgery? antiforgery) { var processPost = HttpMethods.IsPost(context.Request.Method) && - // Disable POST functionality during exception handling and reexecution. + // Disable POST functionality during exception handling. // The exception handler middleware will not update the request method, and we don't // want to run the form handling logic against the error page. - context.Features.Get() == null && - context.Features.Get() == null; + context.Features.Get() == null; if (processPost) {