Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

Blazor 8.0 SSR: Issue with model binding complex object with child collection

$
0
0

In my Blazor app with no client-side interactivity, I have the following complex object:

public class Invoice{    [Required]    public string? Customer { get; set; }    public List<InvoiceLine> Lines { get; set; } = [];}public class InvoiceLine{    [Required]    public string? Item { get; set; }    public decimal Amount { get; set; }}

My invoice page component looks as follows:

@page "/Sales/Invoice"@inject ILogger<InvoicePage> Logger<PageTitle>Invoice</PageTitle><h1>Invoice</h1><EditForm Model="Invoice" OnValidSubmit="Submit" FormName="InvoiceForm"><DataAnnotationsValidator /><div class="row mt-2"><div class="offset-2 col-4"><ValidationSummary Model="Invoice" /></div></div><div class="row mb-2"><label for="Invoice.Customer" class="col-2 col-form-label text-end">Customer</label><div class="col-4"><InputText @bind-Value="Invoice.Customer" class="form-control" /><ValidationMessage For="@(() => Invoice.Customer)" /></div></div><div class="row mt-2"><div class="col-6"><table id="Lines" class="table table-bordered mt-2"><thead><tr><th>Item</th><th>Amount</th><th></th></tr></thead><tbody>                    @for (int i = 0; i < Invoice.Lines.Count; i++)                    {                        var line = Invoice.Lines[i];<tr><td><InputText @bind-Value="line.Item" class="form-control" name="@($"Invoice.Lines[{i}].Item")" /><ValidationMessage For="@(() => line.Item)" /></td><td><InputNumber @bind-Value="line.Amount" class="form-control" name="@($"Invoice.Lines[{i}].Amount")" /><ValidationMessage For="@(() => line.Amount)" /></td><td><button type="button" class="btn btn-sm btn-secondary">Remove line</button></td></tr>                    }</tbody><tfoot><tr><td></td><td></td><td><button type="button" class="btn btn-sm btn-secondary">Add line</button></td></tr></tfoot></table></div></div><div class="row mt-4"><div class="offset-2 col-4"><button type="submit" class="btn btn-secondary">Submit</button></div></div></EditForm>@code {    [SupplyParameterFromForm(FormName = "InvoiceForm")]    public Invoice? Invoice { get; set; }    protected override void OnInitialized()    {        Invoice ??= new();        Logger.LogInformation("Invoice.Lines = {Lines}", Invoice.Lines);    }    private void Submit()    {        Logger.LogInformation("Form successfully submitted");    }}

Now, Invoice.Lines becomes null if I submit the form without entering anything, and consequently, null reference execption is thrown at for loop (Log prints 'Invoice.Lines = null'). How come?

The exception goes away if I initialize Invoice.Lines with some line

Invoice ??= new() { Lines = [new InvoiceLine()] };

But, I expect user can delete lines and may even try to submit a form without any line.I can check if Invoice.Lines is null before for loop, but this will be extra code, given thatI already initialized Invoice.Lines in Invoice class to be empty list.

UPDATEThe issue won't resolve even if I initialize Invoice property at the declaration:

[SupplyParameterFromForm(FormName = "InvoiceForm")]public Invoice Invoice { get; set; } = new();

Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>