You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If we have an action method signature like this one: public IActionResult GetTasks(FromQuery] List<string> 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<T> : List<T>, IParsable<CsvList<T>>
{
public static CsvList<T> Parse(string value, IFormatProvider? provider)
{
...
}
public static bool TryParse(string? value, IFormatProvider? provider, out CsvList<T> 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<string> 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<T> 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)
martincostello
added
area-mvc
Includes: MVC, Actions and Controllers, Localization, CORS, most templates
and removed
needs-area-label
Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically
labels
Dec 22, 2024
Is there an existing issue for this?
Describe the bug
Hi,
If we have an action method signature like this one:
public IActionResult GetTasks(FromQuery] List<string> 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 valueIf we provide a custom parsing for the lists, allowing, for example, csv values to be parsed as well, using a custom
CsvList
implementation:(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<string> list)
but, it seems that
CsvList.TryParse()
(norCsvList.Parse
) gets called at all, if the query string doesn't contain thelist
parameter (or it is empty), even though theTryParse()
method can accept nullable string values. The model binding process simply throws an error, saying the parameter is required, instead of calling theTryParse()
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<T>
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]
The text was updated successfully, but these errors were encountered: