Search code examples
asp.net-coreblazor.net-8.0

Why are object attributes empty while binding a model on EditForm in Blazor .net 8?


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(); 
    }
}

Solution

  • 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();