ASP.NET Core多图上传异常:仅存单张且内容为十六进制
ASP.NET Core多图上传问题排查与修复
问题现象
将单图上传代码改为多图版本后,出现两个异常:
- 仅保存一张图片:上传时前端能看到所有选中的图片列表,但后台
Upload方法仅处理第一张 - 图片内容异常:保存的文件无法正常打开,显示为十六进制代码
问题代码
UploadModel.cs
using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace SaveImagesTest.Models { public class UploadModel { public List<string> Name { get; set; } public List<IFormFile> File { get; set; } } }
FileUploadController.cs
using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using SaveImagesTest.Models; using Microsoft.AspNetCore.Hosting; using System.IO; namespace SaveImagesTest.Controllers { public class FileUploadController : Controller { [Obsolete] private IHostingEnvironment hostingEnv; [Obsolete] public FileUploadController(IHostingEnvironment env) { this.hostingEnv = env; } [HttpGet] public IActionResult Upload() { return View(); } [HttpPost] [Obsolete] public IActionResult Upload(UploadModel upload) { var FileDic = "Files"; string FilePath = Path.Combine(hostingEnv.WebRootPath, FileDic); if (!Directory.Exists(FilePath)) Directory.CreateDirectory(FilePath); int count = 0; foreach (var file in upload.File) { var fileName = ++count; var filePath = Path.Combine(FilePath, fileName.ToString()); using (FileStream fs = System.IO.File.Create(filePath)) { file.CopyTo(fs); continue; } } return View("Index"); } } }
index.cshtml
@model SaveImagesTest.Models.UploadModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>ASP.NET Core save image to folder </title> </head> <body> @using (Html.BeginForm("Upload", "FileUpload", FormMethod.Post, new { enctype = "multipart/form-data" })) { <table> <tr> <td>File Upload:</td> <td> <input type="file" id="File_Upload" name="File" onchange="readURL(this);" accept="image/*" multiple /> <br /> </td> </tr> <tr> <td>File Name:</td> <td> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </td> </tr> <tr> <td></td> <td> <input type="submit" value="Upload" class="btn-default" /> </td> </tr> </table> } </body> </html>
修复方案
1. 解决仅处理单张图片的问题
前端文件输入框的name属性需要改为数组格式File[],ASP.NET Core模型绑定才能正确识别并接收多个文件:
<input type="file" id="File_Upload" name="File[]" onchange="readURL(this);" accept="image/*" multiple />
2. 解决图片内容为十六进制的问题
- 保存文件时未保留原扩展名,导致系统无法识别文件类型,需添加扩展名处理
- 替换过时的
IHostingEnvironment为IWebHostEnvironment(ASP.NET Core 3.0+推荐使用)
修复后完整代码
FileUploadController.cs(修复后)
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Hosting; using System.IO; using SaveImagesTest.Models; namespace SaveImagesTest.Controllers { public class FileUploadController : Controller { private readonly IWebHostEnvironment _webHostEnv; public FileUploadController(IWebHostEnvironment webHostEnv) { _webHostEnv = webHostEnv; } [HttpGet] public IActionResult Upload() { return View(); } [HttpPost] public IActionResult Upload(UploadModel upload) { var fileDir = "Files"; string rootPath = Path.Combine(_webHostEnv.WebRootPath, fileDir); if (!Directory.Exists(rootPath)) Directory.CreateDirectory(rootPath); int count = 0; foreach (var file in upload.File) { if (file.Length <= 0) continue; // 保留原文件扩展名 var extension = Path.GetExtension(file.FileName); var fileName = $"{++count}{extension}"; var fullPath = Path.Combine(rootPath, fileName); using (var fs = System.IO.File.Create(fullPath)) { file.CopyTo(fs); } } return View("Index"); } } }
index.cshtml(修复后)
@model SaveImagesTest.Models.UploadModel @{ Layout = null; } <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>ASP.NET Core 图片保存到文件夹</title> </head> <body> @using (Html.BeginForm("Upload", "FileUpload", FormMethod.Post, new { enctype = "multipart/form-data" })) { <table> <tr> <td>文件上传:</td> <td> <input type="file" id="File_Upload" name="File[]" onchange="readURL(this);" accept="image/*" multiple /> <br /> </td> </tr> <tr> <td>文件名:</td> <td> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </td> </tr> <tr> <td></td> <td> <input type="submit" value="上传" class="btn-default" /> </td> </tr> </table> } </body> </html>
关键修复点总结
- 前端文件输入框
name改为File[],确保模型绑定接收多文件 - 保存文件时保留原扩展名,避免文件类型识别错误
- 替换过时的
IHostingEnvironment为IWebHostEnvironment,符合框架最新规范 - 添加文件长度校验,跳过空文件
内容的提问来源于stack exchange,提问作者user16991782
相关产品推荐
相关产品推荐

