dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.37k stars 9.99k forks source link

Blazor SSR with multiple forms, validation not working #55173

Closed janaka44 closed 6 months ago

janaka44 commented 6 months ago

Requirement: I have a single page with multiple EditForms that are shown/hidden, with a single form appearing at once. Form 1 > Form 2 > Form 3 is how it appears upon valid form submission. It has corresponding model parameters assigned correctly using the FormName syntax. I have to use static SSR in my real application and switching to InteractiveServer isn't an option (due to HttpContext as [CascadingParameter] not working in InteractiveServer mode).

`

[SupplyParameterFromForm(FormName = "loginA")]
public InputModelA InputA { get; set; } = new();

[SupplyParameterFromForm(FormName = "loginB")]
public InputModelB InputB { get; set; } = new();

[SupplyParameterFromForm(FormName = "loginC")]
public InputModelC InputC { get; set; } = new();

` Sample repo (click on Multiple Forms nav menu): https://github.com/janaka44/Blazor-multiple-forms

image

Issue: Only the very 1st form works properly (with validation messages appearing, preventing form submission upon validation errors), but 2nd and 3rd forms :

Reason/Guess I guess due to show/hidden action, the 2nd/3rd forms are not working/initialized properly

Notes When the order of the form is changed, ie the 2nd form is moved as 1st, validation/form submission starts working correctly with the same code. (again 2n/3rd forms not working now)

to show/hide I've tried both:

SteveSandersonMS commented 6 months ago

The validation rules are applied to your forms, but the problem is that you're hiding/showing the forms based on data that isn't preserved across HTTP requests. Your page is using static SSR, so it's stateless except for any data you round-trip through the form posts.

So to be specific, your showFormX and showFormXcss fields lose their values and reset to defaults on every form post, hence when form B is posted, it goes back to showing form A.

To fix this, you need to preserve these fields through the HTTP form posts, for example by embedding their values in the forms as hidden fields.

janaka44 commented 6 months ago

@SteveSandersonMS Thanks. I can get the show/hide flag state as you mentioned, but the main issue is why the Blazor validation is not able to work even when the same components are made visible. It seems the DataAnnotationsValidator and ValidationMessage components should be visible at all times for validation messages to work properly. Even though one form's controls + these validation components are made visible at the end of OnIntializedAsync it isn't enough for validation to work.

SteveSandersonMS commented 6 months ago

When I tried your code, the validation messages on the 2nd form did get rendered into the DOM - they were just hidden by your CSS rule.