Per MrC's suggestion I created a minimal reproducible example, and the problem still happens! I still get the validation error message "The value '' is not valid for 'MyNullableInt'."
I had to alter Mr C's example slightly, since I need to retrieve the values from my submitted form and not simply new it up after a submit, but otherwise this is about as stripped-down as I can get.
I noticed one additional problem: the "@onclick" event in my column header, rendered from the search results, never fires.
Finally, I found that Console.WriteLine has no effect, so injected a logger, which writes to my Visual Studio output window when I run on my local host.
I should add, this component worked properly in a Blazor web assembly page that had in v1 of this project--no bizarre validation message for the nullable int, no issue with the column header onclick event. I switched to Blazor server and re-created this component, but once I made that switch these two problems immediately appeared.
I am using .Net 8, creating a new Blazor server project in Visual Studio 2022, and I never anticipated spending this much time on these two issues. The minimally reproducible example is below.
@page "/Test"
@using Microsoft.Extensions.Logging
@inject ILogger<Test> _logger
<PageTitle>Test</PageTitle>
<h1>Test</h1>
@if(TestModel != null)
{
<EditForm Model="TestModel" OnValidSubmit="HandleValidSubmit" FormName="TestModel1">
<ValidationSummary />
<div class="row g-3">
<div class="col-md-4">
<label for="myNullableInt" class="form-label">Nullable Int</label>
<InputNumber id="myNullableInt" class="form-control" @bind-Value="TestModel.MyNullableInt" />
</div>
<div class="col-md-4">
<label for="myString" class="form-label">Nullable String</label>
<InputText id="myString" class="form-control" @bind-Value="TestModel.MyString" />
</div>
<div class="col-md-4">
<label for="MyInt" class="form-label">Int</label>
<InputNumber id="MyInt" class="form-control" @bind-Value="TestModel.MyInt" />
</div>
</div>
<div class="mt-3">
<button type="submit" class="btn btn-primary">Search</button>
</div>
</EditForm>
}
@if(TestSearchResults != null)
{
<div class="mt-4">
<table class="table table-striped">
<thead>
<tr>
<th><span role="button" @onclick='() => ColumnHeaderClick("MyInt")'>Client</span></th>
<th><span role="button" @onclick='() => ColumnHeaderClick("MyString")'>My String</span></th>
</tr>
</thead>
<tbody>
@foreach(var testSearchResult in TestSearchResults)
{
<tr>
<td>@testSearchResult.MyInt</td>
<td>@testSearchResult.MyString</td>
</tr>
}
</tbody>
</table>
</div>
}
@code {
[SupplyParameterFromForm]
public TestForm? TestModel { get; set; }
private List<TestSearchResult>? TestSearchResults;
protected override async Task OnInitializedAsync()
{
TestModel = TestModel ?? new TestForm();
_logger.LogInformation("In OnInitializedAsync");
}
private async Task ColumnHeaderClick(string columnName)
{
_logger.LogInformation($"ColumnHeaderClick {columnName}");
}
private async Task HandleValidSubmit()
{
_logger.LogInformation("In HandleValidSubmit");
TestSearchResults = new List<TestSearchResult>();
for (int i = TestModel.MyNullableInt.GetValueOrDefault(); i < 100; i++ )
{
TestSearchResults.Add(new TestSearchResult()
{
MyInt = i,
MyString = $"MyName{i}"
});
}
}
public class TestForm
{
public int MyInt { get; set; }
public int? MyNullableInt { get; set; }
public string? MyString { get; set; }
}
public class TestSearchResult
{
public int MyInt { get; set; }
public string MyString { get; set; } = string.Empty;
}
}
Original question below
I have a Blazor server application using .Net 8.
In a Razor component I have an EditForm, where I set the Model to a variable like this:
<EditForm Model="@ClientPayeeSearchModel"
The ClientPayeeSearchModel variable points to an instance of the ClientPayeeSearch class, where I have a nullable int property defined like this:
public int? PayeeID { get; set; }
In my EditForm I am rendering this nullable int like so, using the built-in InputNumber component:
<InputNumber id="payeeID" class="form-control" @bind-Value="ClientPayeeSearchModel.PayeeID" />
My problem is, when I leave this input empty and submit the form, I get the validation error message
The value '' is not valid for 'PayeeID'.
Obviously Blazor thinks I'm trying to set this nullable int to an empty string. I expected Blazor to realize that I simply want to leave it null.
How does one render a nullable int in a Blazor EditForm so that it participates in validation properly?