Model binding using IParsable<T> doesn't allow handling of null values
- Dominant language
- C#
- Stars
- 38.4k
- Forks
- 10.9k
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 290
Description
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Describe the bug
Hi,
If we have an action method signature like this one: `public IActionResult GetTasks(FromQuery] List list)`
and we call such a method, with an example url: `/api/tasks?list=` (or omit the list parameter)
ASP.NET will bind the GetTasks' `list` argument to an empty list, instead of a null value
If we provide a custom parsing for the lists, allowing, for example, csv values to be parsed as well, using a custom `CsvList` implementation:
```
public class CsvList : List, IParsable>
{
public static CsvList Parse(string value, IFormatProvider? provider)
{
...
}
public static bool TryParse(string? value, IFormatProvider? provider, out CsvList result)
{
...
}
}
```
(which is a great improvement imho, comparing to custom model binders, value providers, etc. thanks for that!!)
and we also change the action method's signature to: `public IActionResult GetTasks(FromQuery] CsvList list)`
but, it seems that `CsvList.TryParse()` (nor `CsvList.Parse`) gets called at all, if the query string doesn't contain the `list` parameter (or it is empty), even though the `TryParse()` method can accept nullable string values. The model binding process simply throws an error, saying the parameter is required, instead of calling the `TryParse()` with a null value.
It seems sad that we couldn't just handle the null values as well, and still return the empty list if we wanted to, instead of model binder deciding that for us.
Is this a bug or a feature? :)
### Expected Behavior
`IParsable` implementations should be called with null values as well, to allow us to handle all the cases/variations of input values.
### Steps To Reproduce
To keep things simple, I haven't shared any additional code, hoping you'll manage to reproduce this issue easily.
### Exceptions (if any)
_No response_
### .NET Version
9.0.100 (but the project is configured for v8, if that's relevant)
### Anything else?
Host:
Version: 9.0.0
Architecture: x64
Commit: 9d5a6a9aa4
.NET SDKs installed:
8.0.206 [C:\Program Files\dotnet\sdk]
9.0.100 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.6 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 8.0.11 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Microsoft.WindowsDesktop.App 9.0.0 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
Contributor guide
Assessment
This issue has not been assessed yet.