Honor [Consumes] / IAcceptsMetadata on form endpoints#2589
Honor [Consumes] / IAcceptsMetadata on form endpoints#2589jeremydmiller merged 2 commits intoJasperFx:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes OpenAPI request-format discovery for Wolverine form endpoints so that [Consumes] / IAcceptsMetadata is reflected in ApiDescription.SupportedRequestFormats, preventing ASP.NET Core OpenAPI from silently defaulting form endpoints to application/x-www-form-urlencoded and breaking generated multipart clients.
Changes:
- Seed
SupportedRequestFormatsfromIAcceptsMetadatafor form endpoints when no formats are already present. - Add a regression endpoint that declares
[Consumes("multipart/form-data")]on a form-bound parameter. - Add a regression test asserting multipart is present in
SupportedRequestFormatsfor the new endpoint.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Http/WolverineWebApi/Forms/FormEndpoints.cs | Adds a form endpoint decorated with [Consumes("multipart/form-data")] to reproduce the issue. |
| src/Http/Wolverine.Http/HttpChain.ApiDescription.cs | Extends CreateApiDescription to flow IAcceptsMetadata into SupportedRequestFormats for form endpoints. |
| src/Http/Wolverine.Http.Tests/using_form_parameters.cs | Adds a regression test ensuring form endpoints honor consumes metadata in SupportedRequestFormats. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| foreach (var metadata in Endpoint!.Metadata.OfType<IAcceptsMetadata>()) | ||
| { | ||
| foreach (var contentType in metadata.ContentTypes) | ||
| { | ||
| apiDescription.SupportedRequestFormats.Add(new ApiRequestFormat | ||
| { | ||
| MediaType = contentType | ||
| }); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return apiDescription; |
| // fillRequestType only honors [Consumes] / IAcceptsMetadata for body | ||
| // endpoints (HasRequestType && !IsFormData). Without this, form | ||
| // endpoints fall through and ASP.NET Core OpenAPI's GetFormRequestBody | ||
| // defaults SupportedRequestFormats to "application/x-www-form-urlencoded" | ||
| // — silently dropping [Consumes("multipart/form-data")] on file-upload |
| // IAcceptsMetadata when the endpoint has a body request type and is | ||
| // not a form endpoint. Form endpoints used to fall through and rely | ||
| // on ASP.NET Core OpenAPI's "application/x-www-form-urlencoded" | ||
| // default, which silently dropped [Consumes("multipart/form-data")] | ||
| // and caused generated clients (Orval, NSwag) to emit URLSearchParams | ||
| // bodies instead of multipart for file-upload endpoints. |
|
@rmasciarella Thank you for taking this on. OpenAPI is about my least favorite part of working on Wolverine. |
jeremydmiller
left a comment
There was a problem hiding this comment.
Approving — the form-endpoint OpenAPI fix is correct and the regression test demonstrates the bug clearly. Will follow up with the Copilot review's dedup recommendation in a separate PR.
|
@jeremydmiller no worries it just came up for me while vibe coding, i did run it through a few different models from different angles to make sure before i put it up, glad that it was helpful. |
Summary
HttpChain.fillRequestTypeonly honors[Consumes]/IAcceptsMetadatawhen the endpoint has a body request type and is not a form endpoint (HasRequestType && !IsFormData). Form endpoints fall through andapiDescription.SupportedRequestFormatsstays empty.ASP.NET Core 10's
OpenApiDocumentService.GetFormRequestBodythen defaults toapplication/x-www-form-urlencoded:This silently drops
[Consumes("multipart/form-data")]on file-upload endpoints, so generated clients (Orval, NSwag, Kiota) emitURLSearchParamsbodies instead ofFormData— file uploads break at runtime.Fix
Extend
CreateApiDescriptionso that for endpoints with form-source parameters and no formats already populated,IAcceptsMetadataflows intoSupportedRequestFormats:Semantics
[Consumes]→ no change. Wolverine still emits zero formats; MS OpenAPI still defaults toapplication/x-www-form-urlencoded.[Consumes("multipart/form-data")]→ multipart is added toSupportedRequestFormats; MS OpenAPI no longer adds the urlencoded default (itscount == 0guard); spec correctly emits multipart.Regression test
New test endpoint:
New test:
Fails on
main:Passes after the fix:
Test plan
mainRelated
Independent of #2587 (which fixes a separate
ParameterDescriptornull-deref in the same file). Either can land first.