Skip to content

Inconsistencies in parameter binding between Minimal APIs, AoT, and ControllersΒ #62095

@mikekistler

Description

@mikekistler

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 the Required attribute or if the parameter is not nullable.
  • Controllers set required: true only if the parameter has the Required 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    NativeAOTarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etc

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions