feat(aspnetcore-openapi): emit encoding.contentType for IFormFile parts (#216 follow-up)#219
Conversation
…ts (#216) The FluentValidationOperationTransformer now writes requestBody.content["multipart/form-data"].encoding.<part>.contentType for parts restricted via .FileContentType(...), so UIs like Scalar/Swagger UI show the accepted media types (not just the description). Part-name resolution handles both shapes: an inline multipart schema (net9, and some net10 endpoints) and a whole-body $ref to a component (net10). In the $ref case the reference Target is not resolved at operation-transform time, so the component is looked up in context.Document.Components.Schemas by ref id. Test: new Issue216SpikeTests.FileContentType_Emits_Encoding_ContentType verifies the encoding appears in /openapi/v1.json on net9 and net10. Release: 7.1.8-beta.2. Backend matrix is now content-type+size description AND encoding.contentType across all three backends. Full solution green: Swashbuckle 117/117/86, NSwag 3/3, AspNetCore.OpenApi 18/18. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@claude review this PR |
|
Claude finished @avgalex's task in 2m 50s —— View job PR Review: feat(aspnetcore-openapi): emit encoding.contentType for IFormFile parts
Overall: The implementation is clean, well-reasoned, and solves the right problem. The net9/net10 dual-path in
|
| Core logic | ✅ Correct — dual-path $ref resolution is well-handled |
#if OPENAPI_V2 usage |
✅ Consistent with codebase conventions |
| Error safety | ✅ Covered by outer try/catch in TransformAsync |
JsonDocument lifetime in test |
|
| Encoding overwrite | |
| Test assertion on part name | .First() is fragile |
All three issues are minor. The core change is correct and ready to ship. If you want to address any of them, the JsonDocument lifetime issue is the one most likely to cause a flaky test in the future.
… lifetime - FluentValidationOperationTransformer: merge into an existing OpenApiEncoding (set only ContentType) instead of replacing the whole object, preserving any Headers/Style/Explode that an earlier stage may have set (matches the NSwag processor's pattern). - Issue216SpikeTests: dispose the JsonDocument (using) and Clone() the returned JsonElement so it no longer references the document's pooled buffer (latent lifetime bug); select the encoding entry by the "File" part name instead of .First() so the assertion is robust to ordering and self-documenting. Green: AspNetCore.OpenApi 18/18 (net9/net10). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review! Addressed in the latest commit:
Skipped (with reasons):
AspNetCore.OpenApi suite green: 18/18 on net9 and net10. |
|
@claude review this PR |
|
Claude finished @avgalex's task in 1m 51s —— View job PR Review: feat(aspnetcore-openapi): emit encoding.contentType for IFormFile parts
This is a re-review of the current branch state after Previous issues — verified fixedEncoding overwrite → merge ✅ ( mediaType.Encoding ??= new Dictionary<string, OpenApiEncoding>();
if (!mediaType.Encoding.TryGetValue(partKey, out var encoding) || encoding == null)
mediaType.Encoding[partKey] = encoding = new OpenApiEncoding();
encoding.ContentType = string.Join(", ", allowed);Correctly reuses an existing
using var doc = JsonDocument.Parse(json);
return doc.RootElement.GetProperty("paths").GetProperty("/api/upload")
...GetProperty("multipart/form-data").Clone();
Named part lookup ✅ ( var fileEncoding = encoding.EnumerateObject()
.First(property => property.Name.Equals("File", StringComparison.OrdinalIgnoreCase))
.Value;Named lookup, case-insensitive, self-documenting. Correct. Fresh pass — no new issues
Test coverage — CHANGELOG / README — Clear and accurate. The net10 caveat (description is on the shared One minor observation (no action required)In Summary
The implementation is correct and the test fixes address all latent issues. Ready to merge. |
Follow-up to #218 (merged) for issue #216.
The issue author (@marcuscfarias) is on Scalar +
Microsoft.AspNetCore.OpenApiand reported the allowed media types weren't showing. Diagnosis: he's using the new.FileContentType(...)API correctly, but his .NET 10 document emits the file part as a$refto a sharedIFormFilecomponent, whosedescriptionScalar doesn't render in the form-field row — and that backend did not yet emit the machine-readableencoding.contentType.Change
FluentValidationOperationTransformernow writesrequestBody.content["multipart/form-data"].encoding.<part>.contentTypefor parts restricted via.FileContentType(...):Part-name resolution handles both shapes:
$refto a component whoseTargetis not resolved when the operation transformer runs, so the component is looked up incontext.Document.Components.Schemasby the reference id.The backend matrix is now content-type + size on all three backends, both as
descriptionandencoding.contentType.Tests
Issue216SpikeTests.FileContentType_Emits_Encoding_ContentTypeverifies the encoding appears in the live/openapi/v1.jsonon net9 and net10.Full solution green: Swashbuckle 117/117/86 (net8/9/10), NSwag 3/3 (net8/9), AspNetCore.OpenApi 18/18 (net9/10).
Release
Version bumped to 7.1.8-beta.2; pre-release published. CHANGELOG + README matrix updated.
🤖 Generated with Claude Code