Skip to content

docs for big-file-upload via MultiPartReader / IPipeReader / IFormFeature (net9) #35550

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

Merged
merged 31 commits into from
Jun 17, 2025
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1c1218d
init
DeagleGross May 23, 2025
6509db1
init file stream
DeagleGross May 23, 2025
e7ed63b
save
DeagleGross May 23, 2025
281c969
minor
DeagleGross May 23, 2025
881fb55
rollback
DeagleGross May 23, 2025
63aa7a8
no cts
DeagleGross May 23, 2025
1f75b85
sample app
DeagleGross May 23, 2025
0d3f911
add description
DeagleGross May 23, 2025
00a9426
prettify
DeagleGross May 23, 2025
c5646d0
minimal impl as well
DeagleGross May 26, 2025
b209bd0
explanations to sample
DeagleGross May 26, 2025
5dbaf93
AI help
DeagleGross May 26, 2025
d29dca3
fix links
DeagleGross May 26, 2025
bc2a547
remove unneeded tip
DeagleGross May 26, 2025
9c1965a
tmp remove docs
DeagleGross May 29, 2025
74a09e2
docs for file uploads
DeagleGross May 30, 2025
c0174ad
Merge branch 'main' into dmkorolev/big-file-upload-docs
DeagleGross May 30, 2025
82fd5a8
no warning
DeagleGross Jun 5, 2025
3eab678
fix link
DeagleGross Jun 5, 2025
0754d91
github link
DeagleGross Jun 5, 2025
89617c1
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
964deb1
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
5208804
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
c9ecf5c
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
026986b
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
7ada235
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
6770449
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
99e68e1
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
0028878
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
0f18f39
Update aspnetcore/mvc/models/file-uploads.md
DeagleGross Jun 6, 2025
c9748e2
Apply suggestions from code review
guardrex Jun 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions aspnetcore/mvc/models/file-uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,47 @@ The preceding example is similar to a scenario demonstrated in the sample app:

### Upload large files with streaming

For scenarios where large file uploads are required, streaming uploads allow you to process incoming multipart form data directly without buffering the entire file in memory or on disk via model binding. This technique is especially important for files that could exceed server or framework buffering thresholds.

The [sample application for 9.x](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/mvc/models/file-uploads/samples/9.x/FileManagerSample) demonstrates how a server can receive a file and stream the data directly to disk, supporting robust cancellation via the HTTP request's cancellation token.

<xref:Microsoft.AspNetCore.WebUtilities.MultipartReader> is an ASP.NET Core utility for reading files from incoming requests. The following snippet shows how to process a request and stream the file into an `outputStream` (such as a <xref:System.IO.FileStream>):

```csharp
// Read the boundary from the Content-Type header
var boundary = HeaderUtilities.RemoveQuotes(
MediaTypeHeaderValue.Parse(request.ContentType).Boundary).Value;

// Use MultipartReader to stream data to a destination
var reader = new MultipartReader(boundary, Request.Body);
MultipartSection? section;

while ((section = await reader.ReadNextSectionAsync(cancellationToken)) != null)
{
var contentDisposition = section.GetContentDispositionHeader();

if (contentDisposition != null && contentDisposition.IsFileDisposition())
{
await section.Body.CopyToAsync(outputStream, cancellationToken);
}
}
```

<xref:Microsoft.AspNetCore.Http.Features.IFormFeature> is a wrapper around <xref:Microsoft.AspNetCore.WebUtilities.MultipartReader> that doesn't require you to write manual request body parsing code. You can use its <xref:Microsoft.AspNetCore.Http.Features.IFormFeature.ReadFormAsync%2A> method to populate the request's form data, then access uploaded files from the built-in collection:

```csharp
// Get the IFormFeature and read the form
var formFeature = Request.HttpContext.Features.GetRequiredFeature<IFormFeature>();
await formFeature.ReadFormAsync(cancellationToken);

// Access the uploaded file (example: first file)
var filePath = Request.Form.Files.First().FileName;

return Results.Ok($"Saved file at {filePath}");
```

For advanced scenarios, manually parse the raw request body using <xref:Microsoft.AspNetCore.Http.HttpRequest.BodyReader%2A?displayProperty=nameWithType>, which exposes an [`IPipeReader`](/aspnet/core/fundamentals/middleware/request-response) for low-level, high-performance streaming. The sample app includes endpoint handlers that use `IPipeReader` in both minimal APIs and controllers.

The [3.1 example](https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/mvc/models/file-uploads/samples/3.x/SampleApp/Pages/StreamedSingleFileUploadDb.cshtml) demonstrates how to use JavaScript to stream a file to a controller action. The file's antiforgery token is generated using a custom filter attribute and passed to the client HTTP headers instead of in the request body. Because the action method processes the uploaded data directly, form model binding is disabled by another custom filter. Within the action, the form's contents are read using a `MultipartReader`, which reads each individual `MultipartSection`, processing the file or storing the contents as appropriate. After the multipart sections are read, the action performs its own model binding.

The initial page response loads the form and saves an antiforgery token in a cookie (via the `GenerateAntiforgeryTokenCookieAttribute` attribute). The attribute uses ASP.NET Core's built-in [antiforgery support](xref:security/anti-request-forgery) to set a cookie with a request token:
Expand Down