Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

blazor ssr form processing issues #51978

Closed
1 task done
Seanxwy opened this issue Nov 10, 2023 · 9 comments
Closed
1 task done

blazor ssr form processing issues #51978

Seanxwy opened this issue Nov 10, 2023 · 9 comments
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Comments

@Seanxwy
Copy link

Seanxwy commented Nov 10, 2023

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Blazor SSR form submission issue
When submitting a form on a page, OnInitialized and OnParametersSetAsync execute as if the page had just opened before executing the method specified by OnInvalidSubmit.
This causes the logic in OnInitialized and OnParametersSetAsync to be executed multiple times. (For example, for a DataList + QueryCondition form, when the query form is submitted, the query logic is executed first, and then the query condition is processed. (More problematic if there are multiple forms on the page).
Is there a way to recognize POST operations so that POST operations and objects are recognized in OnInitialized or OnParametersSetAsync and the logic is processed as required?

Expected Behavior

When the form is submitted, it is desirable to identify whether the request is GET or POST in OnInitialized or OnParametersSetAsync.
Something like the Razor Pages handler to make it explicit.

Steps To Reproduce

No response

Exceptions (if any)

No response

.NET Version

8.0 -rc2

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Nov 10, 2023
@javiercn
Copy link
Member

@Seanxwy thanks for contacting us.

Can you provide more details on the types of issues you are referring to? There are a couple of things you can do, but the guidance is as follows:

  • Always perform your initialization logic within OnInitialized/OnParametersSet (If you were doing it on the property).
  • Blazor will only bind the data on first render, not after you've modified it.
  • You have access to HttpContext via a CascadingValue and can determine whether the request is a POST (and do something in response).

In the blazor model, the page renders normally in response to a post request, and only after it has rendered the first time, it processes any action that might have been triggered by a form from the client. The reasons for this behavior are two:

  • We don't know what form to dispatch to until it has been rendered on the page.
  • There are aspects that Blazor defines as part of the renderer like Validation and Authorization that are only known after a concrete form has rendered.

@SteveSandersonMS
Copy link
Member

@Seanxwy Possibly the simplest way to achieve what you're asking is just to have some [SupplyParameterFromForm] parameter in your component, and then inside OnInitializedAsync, check if it's nonnull. If you've received some data, you're processing a form post.

@Seanxwy
Copy link
Author

Seanxwy commented Nov 10, 2023

@Seanxwy
Copy link
Author

Seanxwy commented Nov 10, 2023

实现您所要求的最简单方法可能是在组件中加入一些参数,然后在其中检查它是否为非空。如果您收到了一些数据,则表示您正在处理表单帖子。[SupplyParameterFromForm]``OnInitializedAsync

Adding a parameter is not elegant. This is especially true when url parameters can be used as form field values.Just like this

image

@javiercn
Copy link
Member

javiercn commented Nov 13, 2023

@Seanxwy something like this should work:

https://github.com/Seanxwy/BlazorDemo/blob/master/BlazorDemo/Components/Pages/Home.razor#L52
```csharp
-    public Address Model { get; set; } = new();
+    public Address Model { get; set; } = default!;
protected override Task OnParametersSetAsync()
{
+    Model = switch (model, Id) =>
+    {
+        (null, null) => new(),
+        (var m, null) => m,
+        (null, var id) when id <= 0 => new(),
+        (null, _) => LoadData(),
+        (var m, var id) when m.Id != Id => LoadData(),
+    }
}

In general, you need to move the Model to a field, as it's going to cause problems if you use the prop as a state variable.

The general recommendation is:

  • Check whether the current Model is valid (exists and has a valid ID, or take appropriate action (load when you have a valid ID that doesn't match the model, or create a new instance for the UI)

@Seanxwy
Copy link
Author

Seanxwy commented Nov 14, 2023

I think this is not a good way to handle it, and it is not friendly to multi-forms and complex scenarios

@javiercn
Copy link
Member

@Seanxwy thanks for the additional details. Sure, I might have oversimplified this and made it more complex. In the end, it can be done as follows

public override OnInitialized()
{
  Model ??= new();
}

public override OnParametersSet()
{
   if(Id != Model.Id) {
       LoadData()
   }
}

The only time you really worry about SSR and [SupplyParameterFromForm] is on the initial request.

@javiercn javiercn added question ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. labels Nov 24, 2023
@ghost ghost added the Status: Resolved label Nov 24, 2023
@Seanxwy
Copy link
Author

Seanxwy commented Nov 25, 2023

This is just a simple example, but the actual project will face very complex problems. I really want to use ssr a lot to improve the performance of the project. But at present ssr makes people feel that the completion is very low, I am sorry that the project can only continue to maintain the server mode.

However, the interaction performance and experience of server mode are greatly affected by the stability of the network. While 8.0 is a huge improvement, it's still not very satisfying

@ghost
Copy link

ghost commented Nov 26, 2023

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@ghost ghost closed this as completed Nov 26, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Feb 7, 2024
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved
Projects
None yet
Development

No branches or pull requests

3 participants