-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
There are some subtle differences in parameter binding between Minimal APIs, Minimal APIs compiled for AoT, and Controller-based APIs.
In particular, the way nullability and the RequiredAttribute are handled varies, as well as how these are represented in the generated OpenAPI.
I created a project that explores the combinations of nullability and required for both value and ref params:
https://github.com/mikekistler/aspnet-param-binding
I ran tests and summarized the results in the README.md. My analysis of these results follows.
OpenAPI required
- Minimal APIs (AoT or not) set
required: true
if the parameter has theRequired
attribute or if the parameter is not nullable. - Controllers set
required: true
only if the parameter has theRequired
attribute.
I think Minimal APIs should adopt the behavior of Controllers to make these consistent.
Handling of omitted param
- Minimal APIs (AoT or not) appear to treat an omitted parameter as having a
null
value, and fail the request if the parameter is either required or non-nullable. - Controllers appear to treat omitted parameters differently for value vs reference types:
- For value types, an omitted parameter appears to be treated as having the default value for the type
- For reference types, an omitted parameter appears to be treated as having a
null
value, whether or not the type is nullable.
I think Minimal APIs should fail a request where a parameter with the Required
attribute is omitted, and otherwise set the parameter to its default value.
To achieve full consistency between Minimal APIs and Controllers, Controllers should treat omitted parameters as having their default value -- so the empty string rather than null in the case of a non-nullable string parameter. But this is likely a breaking change so maybe something to avoid.
Handling of empty param value
- Minimal APIs handle empty values differently for AoT and non-AoT scenarios:
- Minimal APIs without AoT appear to treat an empty value as being an empty string, and fails if it cannot assign an empty string to the param (as in the case of the value param).
- Minimal APIs with AoT appear to treat an empty value as being the default value for the type.
- Controllers appear to treat an empty value as if the parameter's value was "null". As a result, it returns 400 if param is not nullable, or if param is required, and otherwise sets it to null.
I think Minimal APIs without AoT should change to be consistent with AoT and treat an empty value as being the default value for the type.
This does not resolve the inconsistency between Minimal APIs and Controllers, but that's probably not fixable without a breaking change to Controllers.