使用FormData向Razor页面POST请求触发400错误的排查求助
.NET 8 Razor Pages 文件上传AJAX提交400错误问题
问题现象
- 使用
myform.serialize()提交表单数据时,可正常调用页面后端的OnPost方法; - 改用
FormData封装文件和表单数据后,向页面自身的OnPost方法发起AJAX请求时,触发400 Bad Request错误,后端断点完全未触发; - 测试发现,将FormData提交到Controller的
SaveUserReference接口可正常获取文件和数据,页面的OnGet、OnGetData等方法也能正常调用,仅FormData提交到页面OnPost时出错; - 尝试过多种
contentType、processData参数组合,均无法解决问题。
UPDATE 3:Program.cs代码
//program.cs using Microsoft.EntityFrameworkCore; using Zeel.Onboarding.DataModels; using Zeel.Onboarding.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddDbContext<DataContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); builder.Services.AddScoped<PageMapManager, PageMapManager>(); builder.Services.AddScoped<TranslationManager, TranslationManager>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapRazorPages(); app.Run();
UPDATE 2:可正常运行的Controller提交代码
以下是提交到Controller能正常运行的代码,注释掉的是之前尝试的写法,不要被contentType、processData和dataType的配置迷惑,各种值和组合都试过:
前端AJAX代码
<script> $(document).on("click", "#editLocalFormJs", function (e) { e.preventDefault(); e.stopPropagation(); var myform = $("#frmItemLocalForm"); var valid = myform.valid(); if (valid) { var formData = new FormData(); $(" .fileUpload").each(function () { var fileInput = $(this)[0]; var file = fileInput.files[0]; formData.append($(this).attr("id"), file); }); formData.append("myFormData", myform.serialize()); $.ajax({ url: "/pageprocessing/saveuserreference", data: formData,//myform.serialize(), dataType: "html", contentType: false,//"application/x-www-form-urlencoded", processData: false, method: "post", //type: "post", success: function (result) { $(" .close-button").click(); }, error: function (err) { console.log(err); } }); } }); </script>
对应的Controller端点
public void SaveUserReference() { ... }
UPDATE:关键现象总结
发现一个奇怪的现象:提交到Controller接口可正常获取文件和数据,但提交到页面自身的public void OnPost(...)方法时会触发400错误。页面似乎无法正确处理自身的POST请求,但OnGet和OnGetData方法可以正常调用。浏览器控制台显示400错误,但点击请求链接能正常访问页面,说明路径是有效的。
我的设计是把所有逻辑放在页面内实现自包含,方便复用,这类数据驱动页面已有7-8个且运行正常,这是第一个包含文件上传功能的页面。
原始问题代码
表单(BS5模态框)
<form id="frmItemLocalForm" method="post" name="frmItemLocalForm" novalidate="novalidate" enctype="multipart/form-data"> @Html.AntiForgeryToken() <input type="hidden" name="controlId" id="controlId" value="@ViewData["controlid"]" /> <input type="hidden" name="itemId" id="itemId" value="@ViewData["itemId"]" /> <input type="hidden" asp-for="UserDocument.Created" name="Created" /> <!--Modal Header--> <div class="modal-header"> <h4 class="modal-title">Edit User Document</h4> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <!-- Modal body --> <div class="modal-body"> <div class="row my-1"> <label class="col-form-label col-md-2">Name</label> <div class="col-md-10"> <input type="text" class="form-control" placeholder="Name" asp-for="UserDocument.DocumentName" name="DocumentName" data-rule-required="true" /> </div> </div> <div class="row my-1"> <label class="col-form-label col-md-2">File</label> <div class="col-md-10"> <input type="file" class="form-control fileUpload" placeholder="User Document" name="userdocumentfileupload" id="userdocumentfileupload" data-rule-required="true" required /> <br />@Model.UserDocument?.DocumentName @Model.UserDocument?.FileName </div> </div> </div> <!-- Modal footer --> <div class="modal-footer"> <button type="submit" id="editLocalForm" class="btn btn-primary">OK</button> <button type="button" class="btn btn-danger close-button" data-bs-dismiss="modal">Close</button> </div> </form>
AJAX代码
$(document).on("click", "#editLocalForm", function (e) { e.preventDefault(); e.stopPropagation(); var myform = $("#frmItemLocalForm"); var valid = myform.valid(); if (valid) { var formData = new FormData(); //$(".fileUpload").each(function () { // var fileInput = $(this)[0]; // var file = fileInput.files[0]; // if (file.size > 0) { // formData.append($(this).attr("id"), file); // } //}); //formData.append("myFormData", myform.serialize()); $.ajax({ url: formUrl, data: myform.serialize(),//formData, dataType: "html", contentType: "application/x-www-form-urlencoded", processData: false, method: "post", success: function (result) { $(" .close-button").click(); table.ajax.reload(null, false); }, error: function (err) { console.log(err); } }); } });
后端端点(断点未触发)
public void OnPost() { ... Request.Form.Files... }
内容的提问来源于stack exchange,提问作者djack109
相关产品推荐
相关产品推荐

