ASP.NET Core 2.0 Razor页面使用DropZone上传返回400状态码问题
解决ASP.NET Core 2.0 Razor页面结合DropZone提交返回400的问题
你遇到的400状态码问题,在ASP.NET Core Razor页面里结合DropZone和普通表单字段提交时非常常见,主要是两个核心原因,我给你一步步拆解解决:
1. 缺少CSRF防伪令牌(最常见原因)
ASP.NET Core Razor页面默认强制启用了跨站请求伪造(CSRF)验证,如果你的表单里没有包含防伪令牌,服务器会直接拒绝请求,返回400错误。
解决方法:在你的<form>标签内添加防伪令牌,用Razor的内置方法即可:
@Html.AntiForgeryToken()
或者用标签助手的写法:
<input asp-for="__RequestVerificationToken" type="hidden" />
2. DropZone的自动提交与表单提交冲突
DropZone默认会在文件拖入后自动发起上传请求,但你想要的是点击按钮后同时提交表单字段和上传文件,这时候需要修改DropZone的配置,禁用自动上传,并且让提交按钮触发统一的上传流程,同时带上表单里的其他数据。
完整修改后的代码
DzDemo.cshtml页面
<form method="post" enctype="multipart/form-data" id="myForm"> @Html.AntiForgeryToken() <!-- 必须添加的防伪令牌 --> <input type="text" id="Username" name="Username" placeholder="输入用户名" /> <div class="dropzone" id="my-dropzone" name="mainFileUploader"> <div class="fallback"> <input name="file" type="file" multiple /> </div> </div> </form> <div style="margin-top:15px;"> <button type="button" id="submit-all">开始上传</button> </div> <!-- 引入DropZone的JS(确保你已经引入了对应CSS) --> <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/dropzone.min.js"></script> <script> // 配置DropZone实例 DropZone.options.myDropzone = { autoProcessQueue: false, // 禁用自动上传,等待手动触发 uploadMultiple: true, // 允许多文件上传 parallelUploads: 100, maxFiles: 100, form: document.getElementById('myForm'), // 关联到你的表单 init: function() { var submitBtn = document.querySelector("#submit-all"); var dzInstance = this; // 点击按钮时触发上传队列 submitBtn.addEventListener("click", function() { dzInstance.processQueue(); }); // 在发送请求前,把表单里的其他字段添加到FormData中 dzInstance.on("sendingmultiple", function(data, xhr, formData) { // 添加用户名字段 formData.append("Username", document.getElementById("Username").value); // 如果有其他表单字段,在这里继续append即可 }); } }; </script>
DzDemo.cshtml.cs后台代码
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; namespace YourProjectNamespace.Pages { public class DzDemoModel : PageModel { // 绑定表单里的Username字段 [BindProperty] public string Username { get; set; } // 绑定DropZone上传的文件列表(name要和前端的file对应) [BindProperty] public List<IFormFile> file { get; set; } public async Task<IActionResult> OnPost() { if (!ModelState.IsValid) { return Page(); } // 处理上传的文件和用户名 if (file != null && file.Count > 0) { var uploadPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads"); // 确保上传目录存在 if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } foreach (var uploadedFile in file) { var filePath = Path.Combine(uploadPath, uploadedFile.FileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await uploadedFile.CopyToAsync(stream); } } } // 这里可以添加后续逻辑,比如跳转成功页面 return RedirectToPage("/UploadSuccess"); } } }
关键注意点
- 确保你的表单
enctype="multipart/form-data"已经正确设置,这个你之前已经做了,没问题。 - DropZone的文件参数名默认是
file,所以后台的List<IFormFile>变量名要和它对应,如果你想改名字,可以在DropZone配置里加paramName: "yourCustomName",然后后台变量名也改成对应的。 - 如果你用的是DropZone的CSS,记得在页面里引入,否则样式会不正常。
内容的提问来源于stack exchange,提问作者Prince
相关产品推荐
相关产品推荐

