前端上传PDF至后端时IFormFile参数接收为Null的问题求助
问题:后端IFormFile参数接收为Null的排查与解决
我尝试从客户端上传PDF文件至后端,并将文件存储路径保存到数据库,但后端Controller方法中的cfile(IFormFile类型)参数始终接收为Null值。以下是相关代码:
HTML上传组件
<div class="row mb-3"> <label @* for="upload_file" *@ class="col-sm-2 col-form-label">File Upload</label> <div class="col-sm-8"> <input class="form-control" type="file" id="upload_file" accept="application/pdf" > </div> <div class="col-sm-1"> <input asp-page-handler="Upload" class="btn btn-outline-info" value="Upload" id="btn_upload" /> </div> </div>
后端Controller方法
public async Task<bool> Upload_pdf([FromForm] IFormFile cfile) { string path = ""; bool iscopied = false; try { if (cfile.Length > 0) { string filename = Guid.NewGuid() + Path.GetExtension(cfile.FileName); path = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "Upload")); using (var filestream = new FileStream(Path.Combine(path, filename), FileMode.Create)) { await cfile.CopyToAsync(filestream); } iscopied = true; } } catch (Exception ex) { throw ex; } return iscopied; }
前端jQuery上传代码
$('#upload_file').change(function (e) { try { e.preventDefault(); var myFile = $('#upload_file').val(); var file_type = myFile.split('.').pop(); /* var file_size = myFile.files[0].size;*/ var file_length = myFile.length; var file_size = e.target.files[0].size; if (file_type === 'pdf' || file_type === 'pdf') { if (file_size > 524288) { alert('Please select the file less than 512KB !!!'); $('#upload_file').val(''); } else { var form = new FormData(); form.append('cfile', myFile); $.ajax({ url: '/Form/Upload_pdf', method: 'POST', data: form, cache: false, contentType: false, processData: false, success: function (data) { alert('visited') }, error: function (xhr, type, exception) { alert("Error - " + exception); } }) } } else { $('#upload_file').val(''); alert('Please select only pdf file'); } } catch (e) { alert('Error while uploading -' + e); } })
错误原因分析
- 前端文件获取错误:
$('#upload_file').val()获取的是文件本地路径字符串,而非实际的File对象,FormData必须传入File对象才能被后端正确解析。 - 文件类型判断冗余且不可靠:重复的
file_type === 'pdf'判断无意义,且通过路径字符串分割后缀的方式,无法处理文件名含多个.的情况。 - 事件绑定逻辑混淆:当前绑定的是文件选择框的
change事件,但页面存在独立的上传按钮,用户点击按钮时不会触发上传逻辑,易造成操作混乱。
解决方法
1. 修正前端文件获取逻辑
替换文件获取方式,拿到真实的File对象:
// 替换原myFile赋值代码 var fileInput = $('#upload_file')[0]; var myFile = fileInput.files[0]; // 确保FormData传入File对象 form.append('cfile', myFile);
2. 优化文件类型校验
直接通过File对象的type属性判断,准确性更高:
// 替换原文件类型判断逻辑 if (myFile.type === 'application/pdf') { // 后续大小校验与上传逻辑 }
3. 调整事件绑定(优化体验)
改为点击上传按钮触发上传,同时保留文件选择后的基础校验:
// 存储选中的文件 var selectedFile = null; $('#upload_file').change(function(e) { selectedFile = e.target.files[0]; }); // 点击上传按钮触发逻辑 $('#btn_upload').click(function(e) { e.preventDefault(); if (!selectedFile) { alert('请先选择PDF文件'); return; } // 类型校验 if (selectedFile.type !== 'application/pdf') { alert('请仅选择PDF文件'); $('#upload_file').val(''); selectedFile = null; return; } // 大小校验 if (selectedFile.size > 524288) { alert('请选择小于512KB的文件!'); $('#upload_file').val(''); selectedFile = null; return; } // 发送上传请求 var form = new FormData(); form.append('cfile', selectedFile); $.ajax({ url: '/Form/Upload_pdf', method: 'POST', data: form, cache: false, contentType: false, processData: false, success: function(data) { alert('上传成功'); $('#upload_file').val(''); selectedFile = null; }, error: function(xhr, type, exception) { alert("错误 - " + exception); } }); });
4. 后端补充目录检查(避免写入失败)
确保上传目录存在,防止因目录缺失导致文件写入失败:
path = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "Upload")); // 新增目录检查 if (!Directory.Exists(path)) { Directory.CreateDirectory(path); }
内容的提问来源于stack exchange,提问作者Devender Singh
相关产品推荐
相关产品推荐

