在C# WebAPI开发中,接收前端上传的文件尤其是图片文件是高频需求,通过IFormFile类型可以便捷地获取上传的文件流和相关元数据,本文详细介绍完整的实现流程。

基础接口实现
首先需要在WebAPI控制器中定义接收文件的接口,核心是使用IFormFile类型作为参数,该类型封装了上传文件的所有信息,包括文件名、内容类型、文件流等。
以下是基础的单文件上传接口示例:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.IO;
using System.Threading.Tasks;
[ApiController]
[Route("api/[controller]")]
public class FileController : ControllerBase
{
/// <summary>
/// 接收单个图片文件上传
/// </summary>
/// <param name="file">前端传递的图片文件</param>
/// <returns>上传结果</returns>
[HttpPost("upload")]
public async Task<IActionResult> UploadImage(IFormFile file)
{
// 校验文件是否为空
if (file == null || file.Length == 0)
{
return BadRequest(new { code = 400, msg = "未接收到有效文件" });
}
// 校验文件类型,只允许图片类型
string[] allowedTypes = { "image/jpeg", "image/png", "image/gif" };
if (!Array.Exists(allowedTypes, t => t == file.ContentType))
{
return BadRequest(new { code = 400, msg = "仅支持jpg、png、gif格式的图片" });
}
// 定义文件保存路径,实际开发中可根据需求调整
string uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads", "Images");
// 如果目录不存在则创建
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
// 生成唯一文件名,避免重名覆盖
string fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
string filePath = Path.Combine(uploadPath, fileName);
try
{
// 将文件流保存到指定路径
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
return Ok(new { code = 200, msg = "上传成功", fileName = fileName, filePath = filePath });
}
catch (Exception ex)
{
return StatusCode(500, new { code = 500, msg = "文件保存失败", error = ex.Message });
}
}
}
多文件上传实现
如果需要支持一次上传多个图片文件,只需要将参数改为IFormFile集合即可,以下是多文件上传的接口示例:
[HttpPost("upload-multiple")]
public async Task<IActionResult> UploadMultipleImages(List<IFormFile> files)
{
if (files == null || files.Count == 0)
{
return BadRequest(new { code = 400, msg = "未接收到有效文件" });
}
string uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "Uploads", "Images");
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
var successFiles = new List<string>();
var failFiles = new List<string>();
foreach (var file in files)
{
if (file.Length == 0)
{
failFiles.Add(file.FileName);
continue;
}
string[] allowedTypes = { "image/jpeg", "image/png", "image/gif" };
if (!Array.Exists(allowedTypes, t => t == file.ContentType))
{
failFiles.Add(file.FileName);
continue;
}
string fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
string filePath = Path.Combine(uploadPath, fileName);
try
{
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
successFiles.Add(fileName);
}
catch
{
failFiles.Add(file.FileName);
}
}
return Ok(new {
code = 200,
msg = "上传完成",
successCount = successFiles.Count,
failCount = failFiles.Count,
successFiles = successFiles,
failFiles = failFiles
});
}
前端调用示例
前端可以使用FormData格式传递文件,以下是使用JavaScript的调用示例:
// 单文件上传
async function uploadSingleImage() {
const fileInput = document.getElementById('singleFile');
const file = fileInput.files[0];
if (!file) {
alert('请选择文件');
return;
}
const formData = new FormData();
// 参数名需要和后端IFormFile参数名一致,这里后端参数名是file
formData.append('file', file);
try {
const response = await fetch('https://ipipp.com/api/file/upload', {
method: 'POST',
body: formData
});
const result = await response.json();
console.log(result);
} catch (error) {
console.error('上传失败', error);
}
}
// 多文件上传
async function uploadMultipleImages() {
const fileInput = document.getElementById('multipleFiles');
const files = fileInput.files;
if (files.length === 0) {
alert('请选择文件');
return;
}
const formData = new FormData();
// 参数名需要和后端List<IFormFile>参数名一致,这里后端参数名是files
for (let i = 0; i < files.length; i++) {
formData.append('files', files[i]);
}
try {
const response = await fetch('https://ipipp.com/api/file/upload-multiple', {
method: 'POST',
body: formData
});
const result = await response.json();
console.log(result);
} catch (error) {
console.error('上传失败', error);
}
}
注意事项
- 需要在WebAPI项目的启动配置中设置请求大小限制,默认情况下ASP.NET Core对请求大小有限制,上传大文件时需要调整,可在ConfigureServices中添加如下配置:
services.Configure<IISServerOptions>(options =>
{
options.MaxRequestBodySize = 104857600; // 设置为100MB
});
services.Configure<FormOptions>(options =>
{
options.MultipartBodyLengthLimit = 104857600; // 设置表单上传大小限制为100MB
});
- 文件保存路径不要使用用户上传的原始文件名,避免路径注入攻击,建议使用GUID生成唯一文件名。
- 生产环境中建议将上传的文件保存到云存储或者独立的文件服务器,不要直接保存在应用部署目录。
- 需要对上传文件的类型和大小做严格校验,避免恶意文件上传导致安全问题。