How to receive a file in a web API request in ASP.NET Core
By FoxLearn 3/1/2025 2:57:53 AM 138
To access the IFormFile
object, you can use Request.Form.Files
:
For example, Retrieve the file directly from the request
[Route("[controller]")] [ApiController] public class FilesController : ControllerBase { [HttpPost] public async Task<IActionResult> Post() { IFormFile file = Request.Form.Files.FirstOrDefault(); // Process the file content return Ok($"Received file {file.FileName} with size in bytes {file.Length}"); } }
Alternatively, you can add an IFormFile
parameter directly to your action method, and ASP.NET Core will map the file based on the form field name:
For example, Using an IFormFile
parameter in the method signature
[Route("[controller]")] [ApiController] public class FilesController : ControllerBase { [HttpPost] public async Task<IActionResult> Post(IFormFile file) { // Process the file content return Ok($"Received file {file.FileName} with size in bytes {file.Length}"); } }
Make sure that the parameter name in the method (file
in this case) matches the name attribute in the form's file input field, or else the mapping will fail, and the IFormFile
will be null.
Saving the File to Disk
You can save the file to disk by copying the stream from the IFormFile
object into a file stream.
using System.IO; [HttpPost] public async Task<IActionResult> Post(IFormFile file) { if (file.Length <= 0) return BadRequest("Empty file"); // Strip out any path specifiers (e.g., /../) var originalFileName = Path.GetFileName(file.FileName); // Generate a unique file path var uniqueFileName = Path.GetRandomFileName(); var uniqueFilePath = Path.Combine(@"C:\temp\", uniqueFileName); // Save the file to disk using (var stream = System.IO.File.Create(uniqueFilePath)) { await file.CopyToAsync(stream); } return Ok($"Saved file {originalFileName} with size {file.Length / 1024m:#.00} KB using unique name {uniqueFileName}"); }
In this case, the file is saved to a predefined directory (C:\temp\
), but for production, you should use a configuration setting for the file path.
Using IFormFile
as a Model Property
If you need to handle additional data along with the file, you can include an IFormFile
in a model class:
public class Document { public string Title { get; set; } public string Version { get; set; } public IFormFile File { get; set; } }
Then, bind this model to your method with the [FromForm]
attribute:
[HttpPost] public async Task<IActionResult> Post([FromForm]Document document) { // Process the file return Ok($"Processed document {document.Title} v{document.Version} - {document.File.FileName}"); }
Make sure to include [FromForm]
when using model binding to avoid a 415 Media Not Supported
error.
File Size Limits
By default, Kestrel web server imposes a request size limit of 30 MB, and the size of each section in a multipart request is limited to 128 MB. You can customize these limits, either globally or per action.
[HttpPost] [RequestSizeLimit(60000000)] // Set size limit to 60 MB public async Task<IActionResult> Post(IFormFile file) { // Process file return Ok(); }
If the client exceeds the form size limit or request size limit, it will result in an error.
Receiving Multiple Files
You can handle multiple file uploads in two ways:
- For a fixed number of files, define multiple
IFormFile
parameters. - For an arbitrary number of files, use
IEnumerable<IFormFile>
to receive multiple files in a single parameter.
For example, receive multiple files
[HttpPost] public async Task<IActionResult> Post(IEnumerable<IFormFile> files) { foreach (var file in files) { // Process each file } return Ok(); }
When using IEnumerable<IFormFile>
, ensure the client names the file fields consistently in the form data.
- How to use JsonConverterFactory in C#
- How to serialize non-public properties using System.Text.Json
- The JSON value could not be converted to System.DateTime
- Try/finally with no catch block in C#
- Parsing a DateTime from a string in C#
- Async/Await with a Func delegate in C#
- How to batch read with Threading.ChannelReader in C#
- How to ignore JSON deserialization errors in C#