InputSelect does not bind correctly to Nullable<bool>
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 276
Description
### Is there an existing issue for this?
- [X] I have searched the existing issues
### Describe the bug
If you create a InputSelect control that is bound (via @bind-Value) to a bool?, it does not work in the same way as InputSelect bound to other nullable types (say int or Enum), and it never displays the null value correctly, but always shows the "false" value.
### Expected Behavior
When a Nullable is bound to an InputSelect, the option with value="" should be bound to the null value. This is how other nullable types work with InputSelect, and also is the most useful.
If the model has null, then the option with value="" should be displayed when the form initially shows.
If the select is manually set to the option with value="", then that value should continue to be displayed.
### Steps To Reproduce
```
@page "/"
What is your favorite color?
Select a Color
Red
Green
Blue
How many legs do you have?
Select a Number
1
2
Are you awesome?
Select Yes or No
Yes
No
Submit
@code {
enum Color { Red, Green, Blue };
class InputModel
{
public Color? FavoriteColor { get; set; } = null;
public int? NumberOfLegs { get; set; } = null;
public bool? Awesome { get; set; } = null;
}
InputModel Model = new InputModel();
void Submit()
{
Console.WriteLine($"Color: {Model.FavoriteColor} Legs: {Model.NumberOfLegs} Awesome: {Model.Awesome}");
}
}
```
When this form is initially shown, the Favorite Color and Number of Legs selects show the "Select..." option, but the Awesome select shows "No". In addition, any attempt to set the "Awesome" select to "Select Yes or No" has it change immediate back to No.
### Exceptions (if any)
_No response_
### .NET Version
8.0.200
### Anything else?
I think the fix is to change the `src/Components/Web/src/Forms/InputSelect.cs` implementation of `FormatValueAsString` to something like:
```
protected override string? FormatValueAsString(TValue? value)
{
if (typeof(TValue) == typeof(bool)) {
return (bool)(object)value! ? "true" : "false";
}
else if (typeof(TValue) == typeof(bool?)) {
if (value == null)
return null;
else
return (bool)(object)value ? "true" : "false";
}
return base.FormatValueAsString(value);
}
```
Luckily this method is protected, so I can fix this in the meantime by creating my own component:
```
public class BetterInputSelect: InputSelect
{
protected override string? FormatValueAsString(TValue? value)
{
if (typeof(TValue) == typeof(bool)) {
return (bool)(object)value! ? "true" : "false";
}
else if (typeof(TValue) == typeof(bool?)) {
if (value == null)
return null;
else
return (bool)(object)value ? "true" : "false";
}
return base.FormatValueAsString(value);
}
}
```
But I think the actual InputSelect.cs should be fixed.
Contributor guide
Assessment
This issue has not been assessed yet.