0
votes

I have encountered a weird behavior of InputSelect element in Razor component. On my input form, I have several fields bound with the model (Partner). Some of these fields I placed in form of dropdown selection. Because the bound field's (PartnerCategory) value is the id (integer) I fetch a lookup table from DB with a name corresponding to a selected id.

On a page, I can see all names in the dropdown list. But when I try to insert a record from the form to the database it throws an SQL exception, because InputSelect treats the first value in the list as NULL. Just to be clear - there is no blank value in the dropdown list, and all names are shown. It just takes it's value as NULL. Followingly because the data type is an integer and it converts NULL to zero. And because I don't have an id that is zero in my table, the Insert command fails.

Below is my simplified code

<EditForm Model="@partner">
    <InputSelect @bind-Value="partner.PartnerCategoryId">
        @if (categoryList != null)
        {
            @foreach (var item in categoryList.OrderBy(x => x.PartnerCategoryId))
            {
                <option value="@item.PartnerCategoryId">@item.Name</option>
            }
        }
    </InputSelect>
</EditForm>

@code {
    Partner partner = new Partner();
    private IEnumerable<PartnerCategory> categoryList;

    protected override async Task OnInitializedAsync()
    {
        categoryList = await CategoryService.GetAllAsync();
    }   
}

How can I handle this? Does it bind values to a model before it fetches data from DB?

1

1 Answers

2
votes

To solve this issue you can add <option value="">Select...</option> in your code like this:

 <InputSelect @bind-Value="partner.PartnerCategoryId">
    @if (categoryList != null)
    {
        <option value="">Select...</option>
        @foreach (var item in categoryList.OrderBy(x => x.PartnerCategoryId))
        {
            <option value="@item.PartnerCategoryId">@item.Name</option>
        }
    }
</InputSelect>

And in your PartnerCategory model define the PartnerCategoryId as required. Note that the type of PartnerCategoryId is nullable: int?

[Required]
public int? PartnerCategoryId {get; set;}

This will prevent the 'submission' of your form unless the user has selected a value

To test the new changes: Add the OnValidSubmit attribute to your EditForm component and set its value to "HandleValidSubmit"

Add a HandleValidSubmit method, like this:

private void HandleValidSubmit()
{
   // Put code here to save your record in the database
}

Add a submit button at the bottom of your EditForm:

<p><button type="submit">Submit</button></p>

Run your app, and hit the "Submit" button...As you can see the form is not "submitted", and the select element's borders are painted red.

Here's a complete version of your code:

<EditForm Model="@partner" OnValidSubmit="HandleValidSubmit">
    <InputSelect @bind-Value="partner.PartnerCategoryId">
        @if (categoryList != null)
        {
            <option value="">Select...</option>
            @foreach (var item in categoryList.OrderBy(x => x.PartnerCategoryId))
            {
                <option value="@item.PartnerCategoryId">@item.Name</option>
            }
        }
    </InputSelect>

     <p><button type="submit">Submit</button></p>
</EditForm>

@code {
    Partner partner = new Partner();
    private IEnumerable<PartnerCategory> categoryList;

    protected override async Task OnInitializedAsync()
    {
        categoryList = await CategoryService.GetAllAsync();
    } 

    private void HandleValidSubmit()
    {
       Console.WriteLine("Submitted");
    }  
}