ASP.NET Core  

How to Upload Files in ASP.NET Core Web API?

Introduction

File upload functionality is a common requirement in modern web applications built with ASP.NET Core Web API. Whether handling profile images, documents, PDFs, videos, or large media files, implementing secure and efficient file upload in ASP.NET Core requires proper request handling, validation, and storage strategy. A well-designed file upload system improves performance, security, and scalability in production-grade .NET applications.

Understanding File Upload in ASP.NET Core

ASP.NET Core Web API supports file uploads using multipart/form-data requests. When a client (Angular, React, mobile app, or Postman) sends a file, the server binds it using the IFormFile interface.

The IFormFile interface provides access to:

  • File name

  • Content type

  • File size

  • Stream content

This makes it straightforward to process and store uploaded files.

Step 1: Create File Upload Endpoint

Create a controller in ASP.NET Core Web API:

[ApiController]
[Route("api/[controller]")]
public class FilesController : ControllerBase
{
    [HttpPost("upload")]
    public async Task<IActionResult> Upload(IFormFile file)
    {
        if (file == null || file.Length == 0)
            return BadRequest("No file uploaded.");

        var uploadsFolder = Path.Combine(Directory.GetCurrentDirectory(), "Uploads");

        if (!Directory.Exists(uploadsFolder))
            Directory.CreateDirectory(uploadsFolder);

        var filePath = Path.Combine(uploadsFolder, file.FileName);

        using (var stream = new FileStream(filePath, FileMode.Create))
        {
            await file.CopyToAsync(stream);
        }

        return Ok(new { message = "File uploaded successfully." });
    }
}

This endpoint accepts a single file and stores it inside a local "Uploads" folder.

Step 2: Configure Request Size Limits

By default, ASP.NET Core limits request body size. For large file uploads, configure limits inside Program.cs:

builder.Services.Configure<FormOptions>(options =>
{
    options.MultipartBodyLengthLimit = 104857600; // 100 MB
});

Alternatively, apply a per-endpoint limit:

[RequestSizeLimit(104857600)]

Carefully control upload size to prevent abuse or denial-of-service scenarios.

Step 3: Upload Multiple Files

To handle multiple files:

[HttpPost("upload-multiple")]
public async Task<IActionResult> UploadMultiple(List<IFormFile> files)
{
    foreach (var file in files)
    {
        var filePath = Path.Combine("Uploads", file.FileName);
        using var stream = new FileStream(filePath, FileMode.Create);
        await file.CopyToAsync(stream);
    }

    return Ok("Files uploaded successfully.");
}

This approach is useful for bulk document uploads.

Validating Uploaded Files

File validation is critical for security and data integrity.

Validate File Size

if (file.Length > 5 * 1024 * 1024)
    return BadRequest("File size exceeds limit.");

Validate File Type

var allowedTypes = new[] { ".jpg", ".png", ".pdf" };
var extension = Path.GetExtension(file.FileName).ToLower();

if (!allowedTypes.Contains(extension))
    return BadRequest("Invalid file type.");

Never rely solely on file extension. Validate MIME type when possible.

Storing Files in Different Locations

Depending on architecture, files can be stored in:

  • Local server directory

  • Network file storage

  • Cloud storage (Azure Blob Storage, AWS S3)

  • Database as binary (not recommended for large files)

For scalable production systems, cloud storage is generally preferred.

Returning File URLs

After storing the file, return a URL so the frontend can access it:

var fileUrl = $"https://yourdomain.com/uploads/{file.FileName}";
return Ok(new { url = fileUrl });

Make sure static files middleware is enabled if serving from wwwroot:

app.UseStaticFiles();

Security Best Practices for File Upload

  • Restrict allowed file types

  • Limit maximum file size

  • Scan files for malware if required

  • Rename files to prevent path traversal attacks

  • Store files outside the web root if direct access is not required

  • Use authentication and authorization for upload endpoints

Example of generating unique file names:

var uniqueFileName = $"{Guid.NewGuid()}{extension}";

This prevents overwriting and reduces security risks.

Handling Large File Uploads Efficiently

For very large files:

  • Use streaming instead of loading entire file into memory

  • Enable chunked uploads

  • Configure reverse proxy limits (IIS, Nginx)

  • Monitor memory consumption

Proper configuration ensures stable performance under heavy upload traffic.

File Upload with Angular or Frontend Applications

From frontend (example using JavaScript FormData):

const formData = new FormData();
formData.append('file', selectedFile);

fetch('https://localhost:5001/api/files/upload', {
  method: 'POST',
  body: formData
});

Ensure Content-Type is automatically set to multipart/form-data.

Common File Upload Errors

  • 415 Unsupported Media Type – Incorrect request format

  • 413 Payload Too Large – File exceeds server limit

  • CORS issues – Cross-origin configuration missing

  • Permission denied – Directory access restrictions

Proper logging and validation help diagnose these issues quickly.

Summary

Uploading files in ASP.NET Core Web API involves handling multipart form data using IFormFile, configuring request size limits, validating file type and size, and selecting an appropriate storage strategy such as local storage or cloud-based object storage. By implementing secure validation, renaming files to prevent conflicts, limiting upload size, and optimizing for large file streaming scenarios, developers can build scalable, secure, and high-performance file upload solutions suitable for enterprise-grade .NET applications.