I'm working on a Blazor web app in new hosting mode of Blazor on .NET 8, where I tried to bind a product model to an EditForm, initialized model in OnInitializedAsync()
method, but when the form is submitted, the attributes in the bound model (productModel
) are always empty, despite the input fields being filled out in the UI. I expected the form data to bind correctly to the model.
I did also try to use breakpoints to monitors all values at runtime.
What could be causing the model not to bind properly to the form inputs?
Here is my code:
@page "/insertProduct"
@using DbContext DB
@using System.ComponentModel.DataAnnotations
<h3>Insert New Product</h3>
<EditForm Model="@productModel" OnValidSubmit="@HandleValidSubmit">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="form-group">
<label for="name">Product Name</label>
<InputText id="name" class="form-control" @bind-Value="productModel.Name" />
</div>
<div class="form-group">
<label for="description">Description</label>
<InputTextArea id="description" class="form-control" @bind-Value="productModel.Description" />
</div>
<div class="form-group">
<label for="price">Price</label>
<InputNumber id="price" class="form-control" @bind-Value="productModel.Price" />
</div>
<div class="form-group">
<label for="stock">Stock</label>
<InputNumber id="stock" class="form-control" @bind-Value="productModel.Stock" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</EditForm>
@if (isSubmitted)
{
<div class="alert alert-success" role="alert">
submitted!
</div>
}
@code {
[SupplyParameterFromForm]
private Product productModel {get;set;}
private bool isSubmitted = false;
protected override async Task OnInitializedAsync()
{
productModel = new Product();
}
private async Task HandleValidSubmit()
{
isSubmitted = true;
DB.Products(productModel); // product is empty here
await DB.SaveChangesAsync();
productModel = new Product();
}
}
Because productModel is recreated empty instance on every initialized. It should be
protected override async Task OnInitializedAsync()
{
if (productModel == null)
{
productModel = new Product();
}
}
Or generally shortly used
protected override void OnInitialized() => productModel ??= new Product();