Skip to content

Document IFormFileCollection vs IReadOnlyList<IFormFile> binding behavior in Minimal APIs #37173

@danroth27

Description

@danroth27

Summary

Document the parameter-binding behavior differences between IFormFileCollection and IReadOnlyList<IFormFile> (and related collection types) in Minimal APIs. This was requested by the framework team in dotnet/aspnetcore#66757 (see this comment from @captainsafia).

Page to update

Parameter binding in Minimal API applications — "Binding to forms with IFormCollection, IFormFile, and IFormFileCollection"

Source file: aspnetcore/fundamentals/minimal-apis/includes/parameter-binding8-10.md (around the section anchored at <a name="bind8">).

What needs to be documented

Minimal API form-file binding has three distinct, undocumented behaviors depending on the parameter type:

  1. IFormFileCollection — Always binds to the entire HttpContext.Request.Form.Files collection. The parameter name is ignored; every uploaded file is included regardless of its form field name. This is handled by the Minimal API parameter-binding layer in RequestDelegateFactory and maps directly to HttpContext.Request.Form.Files.

  2. IReadOnlyList<IFormFile> — Binds only the files whose form field name matches the parameter (or property) name. This is handled by the shared form-mapping layer used by Minimal APIs and Blazor, which calls IFormFileCollection.GetFiles(name).

  3. Other collection shapes are not supported. The following bind to empty / are not populated:

    • Interfaces: IEnumerable<IFormFile>, IReadOnlyCollection<IFormFile>, ICollection<IFormFile>, IList<IFormFile>
    • Concrete types: List<IFormFile>, IFormFile[], Collection<IFormFile>, ReadOnlyCollection<IFormFile>

    Users who want a name-scoped collection of files should use IReadOnlyList<IFormFile>; users who want every uploaded file should use IFormFileCollection.

Repro / evidence

Suggested doc change

Add a short subsection (or call-out table) under "Binding to forms with IFormCollection, IFormFile, and IFormFileCollection" that captures the three behaviors above. A table like the following would make the distinction easy to scan:

Parameter type Bound value Honors parameter name?
IFormFileCollection All files in HttpContext.Request.Form.Files No
IFormFile The single file whose form field name matches the parameter name Yes
IReadOnlyList<IFormFile> All files whose form field name matches the parameter name Yes
Other IFormFile collection types (IEnumerable<IFormFile>, List<IFormFile>, IFormFile[], etc.) Not supported — parameter is not populated n/a

It would also be worth adding a one-line note that this same behavior applies to properties on [AsParameters] / form-mapped complex types (since the form-mapping layer is shared with Blazor).

Versions affected

The behavior exists in .NET 7+ Minimal APIs. The doc update should target the >= aspnetcore-8.0 content (the parameter-binding8-10.md include), since that is where the form-file binding section lives.

/cc @tdykstra @wadepickett

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions