ASP.NET MVC Razor表单批量文件上传绑定始终为null问题
文件上传字段绑定为null的解决方案
问题场景
我有一个基于订单金额等选项生成所需文档列表的表单,允许终端用户上传对应文件后点击“全部上传”。但将视图模型绑定回Action时,Upload字段始终为null,其他所有字段均正常。
现有Razor页面代码
<form asp-action="UploadQuotes" class="quoteForm" enctype="multipart/form-data" asp-controller="Home" onsubmit="return jQueryAjaxPost(this);"> @for (int i = 0; i < Model.Count; i++) { <input type="hidden" asp-for="@Model[i].Id"/> <li class="list-group-item list-group-item-action itemClass"> <div class="row"> <div class="col-3"> <div class="form-group"> <select asp-for="@Model[i].SelectedType" class="form-control custom-select" asp-items="@Model[i].Options"></select> <span asp-validation-for="@Model[i].SelectedType" text-danger" style="color:red;"></span> </div> </div> <div class="col-8 text-center"> <input class="form-control" asp-for="@Model[i].Upload" type="file" > </div> <div class="col-1 my-auto"> @if (Model[i].AllowDelete) { <button class="btn ms-0 ps-0" title="Delete" onclick="jQueryAjaxDelete('@Url.Action("DeleteQuote", "Actions", new {id = Model[i].Id })',this)"><i class="fa-solid fa-circle-xmark"></i></button> } </div> </div> </li> } </form>
现有Controller代码
public async Task<IActionResult> UploadQuotes(List<QuoteVM> vm) { foreach(var quote in vm) { var quotePlaceholder = await _unitOfWork.quoteRepo .GetByIdAsync(x => x.Id == quote.Id); var file = _baseFactory.ConvertUpload(quote.Upload); //returns tuple with upload as byte[] quotePlaceholder.Doc = file.Item4; _unitOfWork.quoteRepo.Update(quotePlaceholder); await _unitOfWork.SaveAsync(); } return View(vm); }
解决步骤
1. 修正AJAX提交逻辑
问题核心在于AJAX上传文件不能使用普通的表单序列化,必须通过FormData对象传递,同时禁用jQuery的自动数据处理和 contentType 设置。
修改jQueryAjaxPost函数如下:
function jQueryAjaxPost(form) { // 用表单实例构造FormData,自动包含所有表单字段(包括文件) var formData = new FormData(form); $.ajax({ url: form.action, type: form.method, data: formData, // 禁止jQuery处理数据,避免文件被转成字符串 processData: false, // 禁止设置contentType,让浏览器自动添加正确的multipart/form-data头 contentType: false, success: function (result) { // 这里添加上传成功后的处理逻辑,比如提示或页面刷新 alert("文件上传完成"); }, error: function (xhr) { alert("上传失败,请重试"); } }); return false; // 阻止表单默认的同步提交 }
2. 确认视图模型字段类型
确保QuoteVM中的Upload属性为IFormFile类型(ASP.NET Core中唯一支持文件上传绑定的类型):
public class QuoteVM { public int Id { get; set; } public string SelectedType { get; set; } public IEnumerable<SelectListItem> Options { get; set; } public bool AllowDelete { get; set; } // 必须是IFormFile类型,才能正确接收上传的文件 public IFormFile Upload { get; set; } }
3. 验证表单字段命名
Razor循环中asp-for="@Model[i].Upload"会自动生成name="vm[i].Upload"的属性,这符合ASP.NET Core对集合绑定的要求,无需修改。只要AJAX正确传递FormData,绑定就能正常工作。
内容的提问来源于stack exchange,提问作者user3275950
相关产品推荐
相关产品推荐

