Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent model binding between IFormFileCollection, IReadOnlyList<IFormFile> and other collection types in Minimal APIs #54999

Open
1 task done
KennethHoff opened this issue Apr 7, 2024 · 2 comments
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc Docs This issue tracks updating documentation
Milestone

Comments

@KennethHoff
Copy link

KennethHoff commented Apr 7, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Minimal API form binding works differently based on which interface types you choose to use:

  • IFormFileCollection binds every file regardless of their name.
    • Prior to noticing this issue I always used this type if I wanted to get a collection of files, as it seemed like the obvious one based on the name.
  • IReadOnlyList<IFormFile> binds all the ones with the corresponding names.
    • This is what I thought IFormFileCollection did.
  • All the other collection interfaces (IEnumerable<IFormFile>, IReadOnlyCollection<IFormFile>, IList<IFormFile>, and ICollection<IFormFile>) and their implementations (List<IFormFile>, IFormFile[], Collection<IFormFile>, and ReadOnlyCollection<IFormFile>) do not work at all.
    • This is fine for my use-case, just wanted to mention it for completeness sake.

Expected Behavior

IFormFileCollection respects the name of the property.

Steps To Reproduce

https://github.com/KennethHoff/Repros/tree/master/AspNetCoreMinimalApiInconsistentFormFileCollectionModelBinding

Exceptions (if any)

No response

.NET Version

8.0.202

Anything else?

I realize this is a (huge?) breaking change and this issue will therefore probably never be dealt with, but if nothing else I hope I'll save another developer some time in the future.

The only "documentation" I found of this behaviour is this comment thread on a Pull Request from last year.

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates label Apr 7, 2024
@KennethHoff KennethHoff changed the title Inconsistent model binding between IFormFileCollection, IReadOnlyList<IFormFile> and other collection types Inconsistent model binding between IFormFileCollection, IReadOnlyList<IFormFile> and other collection types in Minimal APIs Apr 8, 2024
@KennethHoff
Copy link
Author

I believe this issue is labeled wrong; I think it should be area-minimal or similar.

@captainsafia
Copy link
Member

@KennethHoff Thanks for reporting this issue and apologies for the delay in response as I work through the triage backlog. 😅

The behavior that you are seeing for IFormFileCollection matches the binding rules that minimal APIs uses. Namely, a parameter of the IFormFileCollection type will bind directly to the HttpRequest.Form.Files property on the HttpContext. Parameter types like IFormFileCollection are handled by the parameter binding layer that is exclusive to minimal APIs and defined in the RequestDelegateFactory code gen layer.

The behavior that you are seeing for IReadOnlyList<IFormFile> comes from the form mapping logic that minimal APIs shares with Blazor. Under the hood, it functions by calling the GetFiles method implemented on IFormFileCollection (see here).

The fact that other collection-based variants of IFormFiles aren't supported is because it's handled by either minimal API's binding layer or the shared form mapping. We could definitely add support for this but the primary reason it's not supported is because the binding layer currently takes a literal representation of IFormFileCollection and its matching APIs.

Overall, I'm a fan of the utility that IFormFileCollection returning the entire collection provides for being able to query things. If we didn't provide it, users would have to either bind from HttpContext.Request or HttpContext.Request.Form if they wanted to interact with multiple files at once. Of course, there's also the option of consuming multiple parameters in your handler.

Your notes about documentation for this behavior are valid though.

@Rick-Anderson @tdykstra Would we be able to add content to this page to cover the parameter binding behavior for IFormFileCollection and IReadOnlyList<IFormFile> as described above? I think this header is the right place to put it.

@captainsafia captainsafia added Docs This issue tracks updating documentation area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates labels Apr 30, 2024
@captainsafia captainsafia added this to the 9.0.0 milestone Apr 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc Docs This issue tracks updating documentation
Projects
None yet
Development

No branches or pull requests

2 participants