Skip to content

Commit 1e29549

Browse files
authored
docs for big-file-upload via MultiPartReader / IPipeReader / IFormFeature (net9) (#35550)
1 parent 0aed1d4 commit 1e29549

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed

aspnetcore/mvc/models/file-uploads.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,47 @@ The preceding example is similar to a scenario demonstrated in the sample app:
415415
416416
### Upload large files with streaming
417417

418+
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.
419+
420+
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.
421+
422+
<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>):
423+
424+
```csharp
425+
// Read the boundary from the Content-Type header
426+
var boundary = HeaderUtilities.RemoveQuotes(
427+
MediaTypeHeaderValue.Parse(request.ContentType).Boundary).Value;
428+
429+
// Use MultipartReader to stream data to a destination
430+
var reader = new MultipartReader(boundary, Request.Body);
431+
MultipartSection? section;
432+
433+
while ((section = await reader.ReadNextSectionAsync(cancellationToken)) != null)
434+
{
435+
var contentDisposition = section.GetContentDispositionHeader();
436+
437+
if (contentDisposition != null && contentDisposition.IsFileDisposition())
438+
{
439+
await section.Body.CopyToAsync(outputStream, cancellationToken);
440+
}
441+
}
442+
```
443+
444+
<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:
445+
446+
```csharp
447+
// Get the IFormFeature and read the form
448+
var formFeature = Request.HttpContext.Features.GetRequiredFeature<IFormFeature>();
449+
await formFeature.ReadFormAsync(cancellationToken);
450+
451+
// Access the uploaded file (example: first file)
452+
var filePath = Request.Form.Files.First().FileName;
453+
454+
return Results.Ok($"Saved file at {filePath}");
455+
```
456+
457+
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.
458+
418459
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.
419460

420461
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:

0 commit comments

Comments
 (0)