You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
v11 update: Binary and file-stream responses in generated OpenAPI documents #37702
FileStreamResult, FileContentHttpResult, and FileStreamHttpResult now produce a type: string / format: binary schema, but fundamentals/minimal-apis/responses.md L285–L287 still recommends Stream and never says the real file result types now appear correctly in OpenAPI documents. That workaround was correct before .NET 11 and is still valid, but it steers readers away from the result types that TypedResults.File and ControllerBase.File() actually return. The same section also has controller guidance at L298 that is true for .NET 11 and false for .NET 10 while rendering inside a >= aspnetcore-10.0 zone.
The FileContentResult sub-area is already documented, near-verbatim, in both tabs of fundamentals/openapi/include-metadata.md: Minimal APIs at L369–L404 and Controllers at L485–L499. Its residual work is cross-reference cleanup only — but that cleanup lands inside the exact responses.md L283–L290 region that the file-stream result types need to rewrite, and inside the same include-metadata.md binary-response section. That's why these are one issue instead of two conflicting PRs.
Product source maps Stream, FileContentResult, FileStreamResult, FileContentHttpResult, and FileStreamHttpResult through the binary-schema path at OpenApiSchemaService.cs L64–L76, with per-type schema names verified below.
✅ Coverage status summary
Legend: ✅ already documented · ✏️ update needed · 🟣 could not determine
#
Feature element from What's New
Status
Where
1
Binary file responses: OpenAPI descriptions are generated for operations that return binary file responses
File stream result types:The release note's .Produces<FileContentHttpResult>(contentType: "application/pdf") pattern
✏️
1. Update — appears nowhere in the docset
17
File stream result types:The controller binary recommendation isn't version-scoped: FileContentResult/FileStreamResult map to binary only in .NET 11, but the line renders for .NET 10
File stream result types: What a .NET 10 controller app should use as the Type for a binary schema
🟣
Not determined. Stream is mapped in .NET 9+, but whether it's the intended controller-side recommendation for .NET 10 needs an author decision. See Review considerations.
🔢 Version applicability
Applies to:>= aspnetcore-11.0 for the new result-type behavior; cross-reference-only prose is version-agnostic where stated. Target moniker:>= aspnetcore-11.0 Earlier versions affected: .NET 10 and earlier don't map the four result types to a binary schema. Change 2 exists specifically to stop .NET 10 readers being told otherwise.
Article
monikerRange
Moniker state
aspnetcore/fundamentals/minimal-apis/responses.md
'>= aspnetcore-7.0'
State D for the .NET 11 additions. The body has one zone: :::moniker range=">= aspnetcore-10.0" opens at L19 and closes at L410. Both responses.md edit regions are inside it.
State C — insert directly. The body has one zone: :::moniker range=">= aspnetcore-11.0" opens at L15 and closes at L768. Its range already equals the target.
⚠️No moniker directive may be placed inside include-metadata.md's tab group. The #### [Minimal APIs](#tab/minimal-apis) / #### [Controllers](#tab/controllers) tab group spans L294–L501. The binary-response edits at L369–L406 and L499 are inside that tab group. They are safe only because the enclosing article zone is already >= aspnetcore-11.0; add prose only, never :::moniker::: directives, in this region.
📋 Coverage gap summary
A developer writes app.MapGet("/report", () => TypedResults.File(pdfStream, "application/pdf")) and wants the OpenAPI document to show a binary response. In How to create responses in Minimal API apps, the file-result section says TypedResults.File returns FileStreamHttpResult, but the OpenAPI guidance then says to write .Produces<Stream>(...). In .NET 11 that indirection is no longer necessary: .Produces<FileStreamHttpResult>(...) or .Produces<FileContentHttpResult>(...) produces the same binary schema and matches the endpoint's actual result type.
On the controller side, responses.md already recommends FileContentResult or FileStreamResult for binary content. That's correct for .NET 11 and wrong for .NET 10, but the line renders for both. Meanwhile include-metadata.md has a complete worked example with emitted YAML for FileContentResult; it needs to say that the other three result types behave identically and link back to the file-result behavior article.
Feature announced in What's New — Describe binary file responses:
ASP.NET Core 11 introduces support for generating OpenAPI descriptions for operations that return binary file responses. This support maps the FileContentResult result type to an OpenAPI schema with type: string and format: binary.
Feature announced in What's New — File stream result types:
FileStreamResult, FileContentHttpResult, and FileStreamHttpResult are now described as binary string schemas in generated OpenAPI documents, so clients see accurate response shapes for endpoints that stream files. Annotate the endpoint with .Produces<FileContentHttpResult>(contentType: "application/pdf") (or the equivalent FileStreamHttpResult/FileStreamResult type) so OpenAPI sees the result type and emits the binary schema.
Breaking change: No. A response that previously had no usable schema or a structurally wrong schema now has a correct one; snapshot tests over generated documents may change.
✏️ 1. Update — aspnetcore/fundamentals/minimal-apis/responses.md, extend the binary bullet and cross-link the worked example (lines 283–290)
Merged from: the "Describe binary file responses" analysis, change 1, and the "File stream result types appear in OpenAPI documents" analysis, change 1.
The two source changes target the same lines and are compatible: the binary-file-responses analysis adds the cross-reference to the worked binary-response example, while the file-stream-result-types analysis adds the .NET 11 result-type guidance after the existing three-schema list. This consolidated edit keeps the Stream guidance, preserves the HTML authoring comment, adds the cross-reference inside the existing bullet, and performs the .NET 11 moniker split once.
Applies to:>= aspnetcore-10.0 for the existing Stream guidance and cross-reference; >= aspnetcore-11.0 for the added file-result-type guidance. Moniker handling:State D — full four-directive split for the .NET 11 paragraph. The insertion point is inside :::moniker range=">= aspnetcore-10.0" (L19 → L410), which is broader than the target. Close it, open >= aspnetcore-11.0, add, close, reopen >= aspnetcore-10.0 with the range expression reproduced character for character. The cross-reference sentence itself is version-agnostic and remains in the existing 10.0 zone. Moniker balance contribution: +2 openers, +2 closers. Location:Lines 283–290, the three-schema bullet list.
Before (lines 283–290):
In particular, there are three common schemas for file results:
-**binary content**, such as PDFs, images, or videos, where the schema should be `type: string, format: binary`.
The recommended `TResponse` for this case is `Stream`. The framework has special logic to map
this type to the `binary` format in the OpenAPI schema.
<!-- Hope we can change this to IBinaryContent if #67145 is approved and implemented -->-**text content**, such as CSV or plain text. Here the schema should be simply `type: string` with no `format`. Use `string` as the `TResponse` for this case.
-**base64-encoded content**, where the schema should be `type: string, format: byte`. It's uncommon to base64-encode file content in an API response, but for legacy reasons this is the schema produced when the `TResponse` is `byte[]`.
After:
In particular, there are three common schemas for file results:
-**binary content**, such as PDFs, images, or videos, where the schema should be `type: string, format: binary`.
The recommended `TResponse` for this case is `Stream`. The framework has special logic to map
this type to the `binary` format in the OpenAPI schema. For a worked example that shows the
generated OpenAPI document for a binary response, see
[Describe binary file responses](xref:fundamentals/openapi/include-metadata#describe-binary-file-responses).
<!-- Hope we can change this to IBinaryContent if #67145 is approved and implemented -->-**text content**, such as CSV or plain text. Here the schema should be simply `type: string` with no `format`. Use `string` as the `TResponse` for this case.
-**base64-encoded content**, where the schema should be `type: string, format: byte`. It's uncommon to base64-encode file content in an API response, but for legacy reasons this is the schema produced when the `TResponse` is `byte[]`.
:::moniker-end
:::moniker range=">= aspnetcore-11.0"
Starting in .NET 11, the file result types themselves also map to the `type: string, format: binary` schema, so `TResponse` can match what the endpoint actually returns:
```csharpapp.MapGet("/report", () =>TypedResults.File(pdfStream, MediaTypeNames.Application.Pdf))
.Produces<FileStreamHttpResult>(contentType: MediaTypeNames.Application.Pdf);
```<xref:Microsoft.AspNetCore.Http.HttpResults.FileContentHttpResult>, <xref:Microsoft.AspNetCore.Http.HttpResults.FileStreamHttpResult>, <xref:Microsoft.AspNetCore.Mvc.FileContentResult>, and <xref:Microsoft.AspNetCore.Mvc.FileStreamResult> all produce the binary schema. `Stream` continues to work and remains a good choice when the result type isn't known at the point where the metadata is declared.
:::moniker-end
:::moniker range=">= aspnetcore-10.0"
Rationale: This is the article a reader is in when deciding how to return a file. The merged edit avoids duplicating the worked YAML, points to the metadata article for it, and also tells .NET 11 readers they can now use the concrete result types that their endpoints actually return. The existing Stream recommendation stays because it's correct in every supported version and remains useful when helper methods erase the result type.
Applies to:>= aspnetcore-11.0 for the FileContentResult/FileStreamResult recommendation Moniker handling:State D — full four-directive split, for the same reason as change 1. This is a second, independent split of the same >= aspnetcore-10.0 zone. Moniker balance contribution: +2 openers, +2 closers. Location:Lines 296–300.
Before (lines 296–300):
As with Minimal APIs, you should choose the `Type` parameter of the `[Produces]` and `[ProducesResponseType]` attributes
that corresponds to the desired OpenAPI schema for your file result responses:
***binary content**: Use `FileContentResult` or `FileStreamResult` to get the `binary` format in the OpenAPI schema.
***text content**: Use `string` to get a simple `type: string` schema.
***base64-encoded content**: Use `byte[]` to get the `byte` format in the OpenAPI schema, though this is uncommon for file results.
After:
As with Minimal APIs, you should choose the `Type` parameter of the `[Produces]` and `[ProducesResponseType]` attributes
that corresponds to the desired OpenAPI schema for your file result responses:
:::moniker-end
:::moniker range=">= aspnetcore-11.0"
***binary content**: Use `FileContentResult` or `FileStreamResult` to get the `binary` format in the OpenAPI schema.
***text content**: Use `string` to get a simple `type: string` schema.
***base64-encoded content**: Use `byte[]` to get the `byte` format in the OpenAPI schema, though this is uncommon for file results.
:::moniker-end
:::moniker range=">= aspnetcore-10.0"
Rationale: The existing bullets are correct for .NET 11 and are kept verbatim; the only change is that they stop rendering for .NET 10, where FileContentResult and FileStreamResult aren't mapped to a binary schema. This change deliberately leaves a hole for .NET 10 rather than guessing at a replacement — see item 19 and Review considerations. An author who knows the intended .NET 10 answer should add an = aspnetcore-10.0 zone with it in the same edit.
✏️ 3. Update — aspnetcore/fundamentals/openapi/include-metadata.md, name all four types and link file-result behavior (lines 371, 382, 404)
Merged from: the "File stream result types" analysis, change 3 (Minimal APIs-tab edits at L371 and L382), and the "Describe binary file responses" analysis, change 2 (cross-reference after L404).
Applies to:>= aspnetcore-11.0 (the existing enclosing zone) Moniker handling:State C — insert directly, add no directive. The enclosing zone is >= aspnetcore-11.0 (L15 → L768) and already equals the target. A directive is additionally forbidden here because the edit region is inside the tab group at L294–L501. Moniker balance contribution: none. 1 / 1 before and after. Location:Line 371, L382, and L404–L406 in the Minimal APIs tab.
Before (line 371):
To describe endpoints that return binary file responses in the OpenAPI document, use the <xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A> extension method with `FileContentResult` as the type parameter to specify the response type and content type:
After (line 371):
To describe endpoints that return binary file responses in the OpenAPI document, use the <xref:Microsoft.AspNetCore.Http.OpenApiRouteHandlerBuilderExtensions.Produces%2A> extension method with a file result type as the type parameter to specify the response type and content type. <xref:Microsoft.AspNetCore.Mvc.FileContentResult>, <xref:Microsoft.AspNetCore.Mvc.FileStreamResult>, <xref:Microsoft.AspNetCore.Http.HttpResults.FileContentHttpResult>, and <xref:Microsoft.AspNetCore.Http.HttpResults.FileStreamHttpResult> all produce a binary schema. The following example uses `FileContentResult`:
Before (line 382):
This generates an OpenAPI schema with `type: string` and `format: binary` for the `FileContentResult` type.
After (line 382):
This generates an OpenAPI schema with `type: string` and `format: binary` for the `FileContentResult` type. The other file result types behave identically, each with a component schema named after the type — for example, `FileStreamHttpResult`.
Before (lines 398–406):
```yamlcomponents:
schemas:
FileContentResult:
type: stringformat: binary```##### Set responses for `ProblemDetails`
After:
```yamlcomponents:
schemas:
FileContentResult:
type: stringformat: binary```File results also support conditional requests and range requests, and `Stream` is an equally valid `TResponse` for a binary schema. For the full set of file result types and their behavior, see [File result return values](xref:fundamentals/minimal-apis/responses#file-result-return-values).##### Set responses for `ProblemDetails`
Rationale: Three sentence-level edits and one cross-reference close the gap without duplicating the worked example. The existing example remains centered on FileContentResult, while the prose states that all four result types generalize to the same binary schema behavior and sends readers to the file-result article for conditional-request and range-request behavior. This is the return leg of the cross-link change 1 opens in the other direction: one sentence rather than a section, because responses.md owns that content and duplicating it here would create a second place to maintain the conditional- and range-request tables. No moniker directive is added inside the tab group.
Applies to:>= aspnetcore-11.0 (the existing enclosing zone) Moniker handling:State C — insert directly, add no directive. The enclosing zone is >= aspnetcore-11.0 (L15 → L768) and already equals the target. The line is inside the L294–L501 tab group, so no moniker directive may be added. Moniker balance contribution: none. 1 / 1 before and after. Location:Line 499 in the Controllers tab.
Before (line 499):
This operation generates the same OpenAPI description as the [Minimal API binary file response example](xref:fundamentals/openapi/include-metadata#describe-binary-file-responses), with `FileContentResult` defined as `type: string` and `format: binary`.
After (line 499):
This operation generates the same OpenAPI description as the [Minimal API binary file response example](xref:fundamentals/openapi/include-metadata#describe-binary-file-responses), with `FileContentResult` defined as `type: string` and `format: binary`. <xref:Microsoft.AspNetCore.Mvc.FileStreamResult> behaves identically and produces a `FileStreamResult` component schema.
Rationale: Preserves the existing cross-link to the Minimal API binary file response example and adds the missing controller-side FileStreamResult generalization. The component-schema naming detail matters because the emitted $ref is derived from the type name.
✅ 5. No change required — TOC
No TOC change required. Both target articles already have TOC entries, and no new article is proposed.
✅ Action plan
Confirm the already-covered rows, especially the existing include-metadata.md Minimal APIs and Controllers examples for FileContentResult.
Apply the include-metadata.md prose edits first (changes 3 and 4). They add no directives and carry no structural risk.
Confirm no :::moniker::: directive exists anywhere between L294 and L501 of include-metadata.md after the edit.
Apply responses.md change 2, then change 1 — bottom-up, so earlier line numbers stay valid.
For both responses.md splits, copy :::moniker range=">= aspnetcore-10.0" from L19 verbatim when reopening.
Verify zone balance: responses.md5:::moniker range= and 5:::moniker-end; include-metadata.md1 and 1.
Build with the .NET 10 moniker. Confirm the Stream recommendation still renders, the new .NET 11 paragraph does not, the controller binary bullets do not, and the article still reaches its end.
Build with the .NET 11 moniker. Confirm the new file-result paragraph and controller bullets each render exactly once.
Decide the 🟣 item before merging: either add an = aspnetcore-10.0 controller recommendation if known, or accept the explicit .NET 10 gap.
Verify every <xref:> resolves, including fundamentals/openapi/include-metadata#describe-binary-file-responses, fundamentals/minimal-apis/responses#file-result-return-values, Microsoft.AspNetCore.Http.HttpResults.FileContentHttpResult, and Microsoft.AspNetCore.Http.HttpResults.FileStreamHttpResult. Note that the first anchor is generated from an ##### heading that appears twice in the article (L369 Minimal APIs, L485 Controllers); the existing L499 link already uses it, so whatever it resolves to today is the established behavior.
Resolve any OpenPublishing.Build warnings.
⚠️ Review considerations
Item 19 is genuinely undetermined and is deliberately not guessed at. Change 2 removes a recommendation from the .NET 10 build without supplying a replacement. Stream has been mapped to binary since .NET 9 and is the obvious candidate, but the article's controller-side samples are attribute-based and no [ProducesResponseType(typeof(Stream), …)] example exists in the docset or in the linked sample project, so it wasn't verified end to end. An author who knows the answer should fill it; a reviewer who doesn't should decide whether a .NET 10 gap is preferable to a .NET 10 error. Don't merge change 2 without making that call explicitly.
The .NET 10 negative is inferred, not read off the 10.0 branch.release/10.0 wasn't among the refs in the analysis clone. The conclusion rests on two independent signals: both implementing commits landed on main after the 10.0 branch cut (dotnet/aspnetcore#63504, 2025-09-15; dotnet/aspnetcore#64562, 2026-03-31), and both are announced as new features in the .NET 11 release notes. If a reviewer can check release/10.0 directly, that would settle change 2 conclusively.
Why change 1's cross-reference isn't scoped to >= aspnetcore-11.0. A separate >= aspnetcore-11.0 split for the cross-reference sentence was considered and rejected. It points at an article whose binary-file content is already gated at >= aspnetcore-11.0 on the other side; gating the pointer as well adds another four-directive split for no reader-visible benefit, and .NET 10 readers following the link simply land on the version of include-metadata.md that applies to them.
Changes 1 and 2 are two independent splits of the same zone. Both split >= aspnetcore-10.0 (L19 → L410) in responses.md, which is why the combined target is 5 / 5 rather than 3 / 3. Apply change 2 before change 1 so earlier line numbers stay valid, and re-confirm the enclosing zone before each.
responses.md's single >= aspnetcore-10.0 zone (L19–L410) is a contention point. Another .NET 11 analysis in this series — C# union types in Minimal APIs, not filed as an issue — also proposes a State D split of that same zone. If any other edit splits it first, re-derive the enclosing zone of L288 before applying change 1; the line numbers and possibly the zone boundaries will have moved, and the 1 / 1 starting balance assumed here will no longer hold.
Why not a new ### OpenAPI schemas for file result types section? Considered and rejected. responses.md already has a section on exactly this topic with the right structure; adding a parallel section would create two places describing the same three schemas.
Cross-issue coordination:include-metadata.md is also edited by three other .NET 11 OpenAPI issues — schemas at L416–L431, Server-Sent Events at L702–L706, and obsolete APIs at L744. Those regions do not overlap this issue's L369–L406 and L499 edits, but line numbers will need re-deriving depending on merge order.
Out of scope for this issue: conditional-request and range-request behavior at responses.md L302–L345, which is already documented and unaffected; and the unresolved IBinaryContent proposal referenced in the HTML comment at L288, which is upstream work not yet shipped.
Note
This is an AI-assisted coverage analysis created by wadepickett.
Target repository:
dotnet/AspNetCore.DocsAnalyzed at commit:
4986136881f2bbf1879f10106467769df5a49932Product source verified at:
dotnet/aspnetcore@1fcd7ef305697a1888f3ede076010350ae9f4f8dSource release notes: Describe binary file responses; File stream result types appear in OpenAPI documents
🎯 Goal
FileStreamResult,FileContentHttpResult, andFileStreamHttpResultnow produce atype: string/format: binaryschema, butfundamentals/minimal-apis/responses.mdL285–L287 still recommendsStreamand never says the real file result types now appear correctly in OpenAPI documents. That workaround was correct before .NET 11 and is still valid, but it steers readers away from the result types thatTypedResults.FileandControllerBase.File()actually return. The same section also has controller guidance at L298 that is true for .NET 11 and false for .NET 10 while rendering inside a>= aspnetcore-10.0zone.The
FileContentResultsub-area is already documented, near-verbatim, in both tabs offundamentals/openapi/include-metadata.md: Minimal APIs at L369–L404 and Controllers at L485–L499. Its residual work is cross-reference cleanup only — but that cleanup lands inside the exactresponses.mdL283–L290 region that the file-stream result types need to rewrite, and inside the sameinclude-metadata.mdbinary-response section. That's why these are one issue instead of two conflicting PRs.Product source maps
Stream,FileContentResult,FileStreamResult,FileContentHttpResult, andFileStreamHttpResultthrough the binary-schema path atOpenApiSchemaService.csL64–L76, with per-type schema names verified below.✅ Coverage status summary
Legend: ✅ already documented · ✏️ update needed · 🟣 could not determine
fundamentals/openapi/include-metadata.mdL369–L371FileContentResultmaps to a schema withtype: stringandformat: binaryinclude-metadata.mdL382 and L398–L404.Produces<FileContentResult>(contentType: MediaTypeNames.Application.Octet)include-metadata.mdL373–L380[ProducesResponseType<FileContentResult>(StatusCodes.Status200OK, MediaTypeNames.Application.Octet)]include-metadata.mdL489–L497responsesentry referencing#/components/schemas/FileContentResultinclude-metadata.mdL386–L394components/schemasentry forFileContentResultinclude-metadata.mdL396–L404include-metadata.mdL499responses.mdbinary-content guidance recommendsStreamand never mentionsFileContentResultor links to the worked examplefundamentals/minimal-apis/responses.mdL283–L290include-metadata.mdbinary section never points back to the file-result articleinclude-metadata.mdL404–L406TypedResults.FilereturnsFileContentHttpResult/FileStreamHttpResultresponses.mdL249ControllerBase.File()returnsFileContentResult/FileStreamResultresponses.mdL259Producesmetadata to be described in OpenAPIresponses.mdL267–L277type: string, format: binaryresponses.mdL285 andinclude-metadata.mdL382FileStreamResultproduces a binary schema for controllersresponses.mdL298 — documented, but see item 17 for its version scopingFileContentHttpResultandFileStreamHttpResultproduce a binary schema for Minimal APIsresponses.mdL283–L290 offers onlyStream.Produces<FileContentHttpResult>(contentType: "application/pdf")patternFileContentResult/FileStreamResultmap to binary only in .NET 11, but the line renders for .NET 10responses.mdL296–L300FileContentResultamong the four binary-capable result typesinclude-metadata.mdL369–L404 and L485–L499Typefor a binary schemaStreamis mapped in .NET 9+, but whether it's the intended controller-side recommendation for .NET 10 needs an author decision. See Review considerations.🔢 Version applicability
Applies to:
>= aspnetcore-11.0for the new result-type behavior; cross-reference-only prose is version-agnostic where stated.Target moniker:
>= aspnetcore-11.0Earlier versions affected: .NET 10 and earlier don't map the four result types to a binary schema. Change 2 exists specifically to stop .NET 10 readers being told otherwise.
monikerRangeaspnetcore/fundamentals/minimal-apis/responses.md'>= aspnetcore-7.0':::moniker range=">= aspnetcore-10.0"opens at L19 and closes at L410. Bothresponses.mdedit regions are inside it.aspnetcore/fundamentals/openapi/include-metadata.md'>= aspnetcore-9.0':::moniker range=">= aspnetcore-11.0"opens at L15 and closes at L768. Its range already equals the target.Evidence for the version boundary:
Mvc.FileContentResult7dbebe9df7— dotnet/aspnetcore#63504Mvc.FileStreamResult,FileContentHttpResult,FileStreamHttpResulta6faeae3e7— dotnet/aspnetcore#64562Moniker balance:
responses.mdinclude-metadata.md📋 Coverage gap summary
A developer writes
app.MapGet("/report", () => TypedResults.File(pdfStream, "application/pdf"))and wants the OpenAPI document to show a binary response. In How to create responses in Minimal API apps, the file-result section saysTypedResults.FilereturnsFileStreamHttpResult, but the OpenAPI guidance then says to write.Produces<Stream>(...). In .NET 11 that indirection is no longer necessary:.Produces<FileStreamHttpResult>(...)or.Produces<FileContentHttpResult>(...)produces the same binary schema and matches the endpoint's actual result type.On the controller side,
responses.mdalready recommendsFileContentResultorFileStreamResultfor binary content. That's correct for .NET 11 and wrong for .NET 10, but the line renders for both. Meanwhileinclude-metadata.mdhas a complete worked example with emitted YAML forFileContentResult; it needs to say that the other three result types behave identically and link back to the file-result behavior article.Feature announced in What's New — Describe binary file responses:
Feature announced in What's New — File stream result types:
Breaking change: No. A response that previously had no usable schema or a structurally wrong schema now has a correct one; snapshot tests over generated documents may change.
📁 Affected files
aspnetcore/fundamentals/minimal-apis/responses.mdaspnetcore/fundamentals/minimal-apis/responses.mdaspnetcore/fundamentals/openapi/include-metadata.mdaspnetcore/fundamentals/openapi/include-metadata.mdTarget article uids:
fundamentals/minimal-apis/responses,fundamentals/openapi/include-metadata📝 Proposed changes
✏️ 1. Update —
aspnetcore/fundamentals/minimal-apis/responses.md, extend the binary bullet and cross-link the worked example (lines 283–290)Merged from: the "Describe binary file responses" analysis, change 1, and the "File stream result types appear in OpenAPI documents" analysis, change 1.
The two source changes target the same lines and are compatible: the binary-file-responses analysis adds the cross-reference to the worked binary-response example, while the file-stream-result-types analysis adds the .NET 11 result-type guidance after the existing three-schema list. This consolidated edit keeps the
Streamguidance, preserves the HTML authoring comment, adds the cross-reference inside the existing bullet, and performs the .NET 11 moniker split once.Applies to:
>= aspnetcore-10.0for the existingStreamguidance and cross-reference;>= aspnetcore-11.0for the added file-result-type guidance.Moniker handling: State D — full four-directive split for the .NET 11 paragraph. The insertion point is inside
:::moniker range=">= aspnetcore-10.0"(L19 → L410), which is broader than the target. Close it, open>= aspnetcore-11.0, add, close, reopen>= aspnetcore-10.0with the range expression reproduced character for character. The cross-reference sentence itself is version-agnostic and remains in the existing 10.0 zone.Moniker balance contribution: +2 openers, +2 closers.
Location: Lines 283–290, the three-schema bullet list.
Before (lines 283–290):
After:
Rationale: This is the article a reader is in when deciding how to return a file. The merged edit avoids duplicating the worked YAML, points to the metadata article for it, and also tells .NET 11 readers they can now use the concrete result types that their endpoints actually return. The existing
Streamrecommendation stays because it's correct in every supported version and remains useful when helper methods erase the result type.✏️ 2. Update —
aspnetcore/fundamentals/minimal-apis/responses.md, version-scope the controller binary bullet (lines 296–300)Applies to:
>= aspnetcore-11.0for theFileContentResult/FileStreamResultrecommendationMoniker handling: State D — full four-directive split, for the same reason as change 1. This is a second, independent split of the same
>= aspnetcore-10.0zone.Moniker balance contribution: +2 openers, +2 closers.
Location: Lines 296–300.
Before (lines 296–300):
After:
Rationale: The existing bullets are correct for .NET 11 and are kept verbatim; the only change is that they stop rendering for .NET 10, where
FileContentResultandFileStreamResultaren't mapped to a binary schema. This change deliberately leaves a hole for .NET 10 rather than guessing at a replacement — see item 19 and Review considerations. An author who knows the intended .NET 10 answer should add an= aspnetcore-10.0zone with it in the same edit.✏️ 3. Update —
aspnetcore/fundamentals/openapi/include-metadata.md, name all four types and link file-result behavior (lines 371, 382, 404)Merged from: the "File stream result types" analysis, change 3 (Minimal APIs-tab edits at L371 and L382), and the "Describe binary file responses" analysis, change 2 (cross-reference after L404).
Applies to:
>= aspnetcore-11.0(the existing enclosing zone)Moniker handling: State C — insert directly, add no directive. The enclosing zone is
>= aspnetcore-11.0(L15 → L768) and already equals the target. A directive is additionally forbidden here because the edit region is inside the tab group at L294–L501.Moniker balance contribution: none. 1 / 1 before and after.
Location: Line 371, L382, and L404–L406 in the Minimal APIs tab.
Before (line 371):
After (line 371):
Before (line 382):
After (line 382):
Before (lines 398–406):
After:
Rationale: Three sentence-level edits and one cross-reference close the gap without duplicating the worked example. The existing example remains centered on
FileContentResult, while the prose states that all four result types generalize to the same binary schema behavior and sends readers to the file-result article for conditional-request and range-request behavior. This is the return leg of the cross-link change 1 opens in the other direction: one sentence rather than a section, becauseresponses.mdowns that content and duplicating it here would create a second place to maintain the conditional- and range-request tables. No moniker directive is added inside the tab group.✏️ 4. Update —
aspnetcore/fundamentals/openapi/include-metadata.md, update the Controllers-tab note (line 499)Applies to:
>= aspnetcore-11.0(the existing enclosing zone)Moniker handling: State C — insert directly, add no directive. The enclosing zone is
>= aspnetcore-11.0(L15 → L768) and already equals the target. The line is inside the L294–L501 tab group, so no moniker directive may be added.Moniker balance contribution: none. 1 / 1 before and after.
Location: Line 499 in the Controllers tab.
Before (line 499):
After (line 499):
Rationale: Preserves the existing cross-link to the Minimal API binary file response example and adds the missing controller-side
FileStreamResultgeneralization. The component-schema naming detail matters because the emitted$refis derived from the type name.✅ 5. No change required — TOC
No TOC change required. Both target articles already have TOC entries, and no new article is proposed.
✅ Action plan
include-metadata.mdMinimal APIs and Controllers examples forFileContentResult.include-metadata.mdprose edits first (changes 3 and 4). They add no directives and carry no structural risk.:::moniker:::directive exists anywhere between L294 and L501 ofinclude-metadata.mdafter the edit.responses.mdchange 2, then change 1 — bottom-up, so earlier line numbers stay valid.responses.mdsplits, copy:::moniker range=">= aspnetcore-10.0"from L19 verbatim when reopening.responses.md5:::moniker range=and 5:::moniker-end;include-metadata.md1 and 1.Streamrecommendation still renders, the new .NET 11 paragraph does not, the controller binary bullets do not, and the article still reaches its end.= aspnetcore-10.0controller recommendation if known, or accept the explicit .NET 10 gap.<xref:>resolves, includingfundamentals/openapi/include-metadata#describe-binary-file-responses,fundamentals/minimal-apis/responses#file-result-return-values,Microsoft.AspNetCore.Http.HttpResults.FileContentHttpResult, andMicrosoft.AspNetCore.Http.HttpResults.FileStreamHttpResult. Note that the first anchor is generated from an#####heading that appears twice in the article (L369 Minimal APIs, L485 Controllers); the existing L499 link already uses it, so whatever it resolves to today is the established behavior.Streamhas been mapped to binary since .NET 9 and is the obvious candidate, but the article's controller-side samples are attribute-based and no[ProducesResponseType(typeof(Stream), …)]example exists in the docset or in the linked sample project, so it wasn't verified end to end. An author who knows the answer should fill it; a reviewer who doesn't should decide whether a .NET 10 gap is preferable to a .NET 10 error. Don't merge change 2 without making that call explicitly.release/10.0wasn't among the refs in the analysis clone. The conclusion rests on two independent signals: both implementing commits landed onmainafter the 10.0 branch cut (dotnet/aspnetcore#63504, 2025-09-15; dotnet/aspnetcore#64562, 2026-03-31), and both are announced as new features in the .NET 11 release notes. If a reviewer can checkrelease/10.0directly, that would settle change 2 conclusively.>= aspnetcore-11.0. A separate>= aspnetcore-11.0split for the cross-reference sentence was considered and rejected. It points at an article whose binary-file content is already gated at>= aspnetcore-11.0on the other side; gating the pointer as well adds another four-directive split for no reader-visible benefit, and .NET 10 readers following the link simply land on the version ofinclude-metadata.mdthat applies to them.>= aspnetcore-10.0(L19 → L410) inresponses.md, which is why the combined target is 5 / 5 rather than 3 / 3. Apply change 2 before change 1 so earlier line numbers stay valid, and re-confirm the enclosing zone before each.responses.md's single>= aspnetcore-10.0zone (L19–L410) is a contention point. Another .NET 11 analysis in this series — C# union types in Minimal APIs, not filed as an issue — also proposes a State D split of that same zone. If any other edit splits it first, re-derive the enclosing zone of L288 before applying change 1; the line numbers and possibly the zone boundaries will have moved, and the 1 / 1 starting balance assumed here will no longer hold.### OpenAPI schemas for file result typessection? Considered and rejected.responses.mdalready has a section on exactly this topic with the right structure; adding a parallel section would create two places describing the same three schemas.include-metadata.mdis also edited by three other .NET 11 OpenAPI issues — schemas at L416–L431, Server-Sent Events at L702–L706, and obsolete APIs at L744. Those regions do not overlap this issue's L369–L406 and L499 edits, but line numbers will need re-deriving depending on merge order.responses.mdL302–L345, which is already documented and unaffected; and the unresolvedIBinaryContentproposal referenced in the HTML comment at L288, which is upstream work not yet shipped.🔗 References
include-metadata.mdL369–L404include-metadata.mdL485–L499responses.mdL265–L300Stream,IFormFile,PipeReader, and all four file result types:OpenApiSchemaService.csL62–L76FileContentResult, confirming the$refin the docs' YAML:JsonTypeInfoExtensions.csL92–L137, asserted atJsonTypeInfoExtensionsTests.csL60–L69OpenApiSchemaService.ResponseSchemas.csL1045, L1068, L1091, L1114FileContentResult: dotnet/aspnetcore#63504