Razor页面与AJAX提交数据时出现Status 400错误排查
问题描述
开发医疗类网站,流程为:收集患者邮箱判断状态——未登录跳转登录页;未注册则自动生成随机密码发邮件完成注册。已登录用户及未登录常规流程正常,但新用户注册后提交后续问题数据时,出现Status 400错误。
后端代码(C#)
public async Task<IActionResult> OnGetCheckUserAsync(string Email) { if (User.Identity.IsAuthenticated) { var UserCred = _userManagmentServices.GetProfileAsync(Email).Result; ProfileModel = new ProfileModel() { Id = UserCred.Id, Email = UserCred.Email, Name = UserCred.Name, Applications = UserCred.Applications, Address = UserCred.Address, City = UserCred.City, DisplayName = UserCred.DisplayName, Phone = UserCred.Phone, PostalCode = UserCred.PostalCode, }; return new JsonResult(ProfileModel); } else { var user = await _userManager.FindByEmailAsync(Email); if (user == null) { string randomString = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*"; Random random = new Random(); char[] myPassword = new char[6]; for (int i = 0; i < 6; i++) { myPassword[i] = randomString[(int)(35 * random.NextDouble())]; } var randomPassword = string.Concat(myPassword); var UserModel = new UserModel() { Email = Email, FirstName = "Mr", LastName = "Patient", Password = randomPassword, PhoneNo = "03000000000", }; var response = await _userManagmentServices.CreateAsync(UserModel); if (response.IsSuccessful) { var Body = $"Dear {UserModel.FirstName + UserModel.LastName} Your password is auto generated successfull and your password is {UserModel.Password}"; await _mailServices.SendEmailNotificationAsync(UserModel.Email, "Auto Generated Password", Body); } if (!response.IsSuccessful) { foreach (var Error in response.Errors) { ModelState.AddModelError("", Error.ToString()); } return new JsonResult("Error while creating your account"); } var UserCred = _userManagmentServices.GetProfileAsync(UserModel.Email).Result; ProfileModel = new ProfileModel() { Id = UserCred.Id, Email = UserCred.Email, Name = UserCred.Name, Applications = UserCred.Applications, Address = UserCred.Address, City = UserCred.City, DisplayName = UserCred.DisplayName, Phone = UserCred.Phone, PostalCode = UserCred.PostalCode, }; return new JsonResult(ProfileModel); } else { application = new FEApplication(); application.Status = Status.Incomplete; application.UserEmail = Email; application.ApplicationType = "Premature Ejaculation"; application.FlowId = await _applicationManagementService.Create(application); var _signinUrl = "../Auth/Signin"; return new JsonResult(_signinUrl); } } } public async Task<IActionResult> OnPostSubmitAsync(FEApplication? application) { if (application.FlowId != null) { application.ApplicationType = "Premature Ejaculation"; if (application.DoctorToKnow == "No" || application.ExplainDoctorToKnow != null) { application.Status = Status.PaymentDue; } else { application.Status = Status.Incomplete; } await _applicationManagementService.UpdatePEAsync(application.FlowId, application); } else { if (User.Identity.IsAuthenticated) { application.PatientUserName = ProfileModel.DisplayName; application.ApplicationType = "Premature Ejaculation"; application.Status = Status.Incomplete; application.UserEmail = User?.Identity?.Name; ProfileModel = _userManagmentServices.GetProfileAsync(application.UserEmail).Result; } else { application.PatientUserName = ProfileModel.DisplayName ?? string.Empty; application.UserEmail = application.UserEmail; } application.Status = Status.Incomplete; application.ApplicationType = "Premature Ejaculation"; application.FlowId = await _applicationManagementService.Create(application); //_application = _applicationManagementService.GetOneById(FlowId); } return new JsonResult(application.FlowId); }
前端代码(JavaScript)
function CheckUserEmail() { $("#modalspinner").show(); var email = document.getElementById("Email").value; $.ajax({ beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken" ]').val()); }, url: "./Start?handler=CheckUser", type: "GET", dataType: "json", data: { Email: email }, success: function (response) { console.log("Success block"); if (response) { $("#modalspinner").hide(); console.log("response " + response) if (response == "../Auth/Signin") { window.location.href = response; } else { if (response.id) { console.log("if block =" + JSON.stringify(response)); var firstName = JSON.stringify(response.displayName) ?? ""; var lastName = JSON.stringify(response.displayName) ?? ""; var email = JSON.stringify(response.email) ?? ""; var phoneNo = JSON.stringify(response.phone); var address = JSON.stringify(response.address) ?? ""; var city = JSON.stringify(response.city); var postalCode = JSON.stringify(response.postalCode) ?? ""; $("#FirstName").val(firstName.replace(/\"/g, "")); $("#LastName").val(lastName.replace(/\"/g, "")); $("#Email").val(email.replace(/\"/g, "")); $("#PhoneNoTextbox").val(phoneNo.replace(/\"/g, "")); $("#CustomerShippingAddress").val(address.replace(/\"/g, "")); $("#CustomerCity").val(city.replace(/\"/g, "")); $("#CustomerPostalCode").val(postalCode.replace(/\"/g, "")); console.log("response data :" + firstName, lastName, email, phoneNo, address, city, postalCode); } else { $("#modalspinner").hide(); console.log("Error while creating new user" + JSON.stringify(response)); } } } }, error: function (response) { console.log("Error block =" + JSON.stringify(response)); $("#modalspinner").hide(); $('#EmailMessage').show(); setTimeout(function () { $('#EmailMessage').hide(); }, 5000); $("#modalspinner").hide(); } }); } function SubmitForm() { /*var flowId = document.getElementById("FlowId").value;*/ var data = $("#ApplicationData").serialize(); console.log("data :" + data); $.ajax({ beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken" ]').val()); }, type: "POST", url: "./Start?handler=Submit", contentType: "application/x-www-form-urlencoded; charset=UTF-8", data: data, success: function (response) { var res = JSON.stringify(response); console.log("Application data saved!"); $("#FlowId").val(res.replace(/\"/g, "")); } }) }
问题排查与解决方案
核心原因推测
- 未登录用户的ProfileModel状态丢失:新用户注册后,
CheckUserEmail返回ProfileModel数据,但用户仍未登录。后续SubmitForm调用后端接口时,页面级的ProfileModel可能未持久化,导致OnPostSubmitAsync中依赖该模型的字段为空,触发模型验证失败。 - 异步方法同步调用异常:代码中多次用
.Result调用异步方法(如_userManagmentServices.GetProfileAsync(Email).Result),易引发线程阻塞或上下文异常,导致数据未正确加载。 - FEApplication模型验证不通过:后端接收参数时,若
UserEmail等必填字段为空、格式不符合要求,ASP.NET Core自动模型验证会直接返回400错误。
具体修复步骤
修复异步调用方式:将所有
.Result替换为await,避免线程死锁:// 原代码 var UserCred = _userManagmentServices.GetProfileAsync(Email).Result; // 修改为 var UserCred = await _userManagmentServices.GetProfileAsync(Email);避免依赖未持久化的ProfileModel:在
OnPostSubmitAsync的未登录分支中,直接使用前端提交的数据,而非依赖页面级变量:else { application.PatientUserName = application.PatientUserName ?? string.Empty; if(string.IsNullOrEmpty(application.UserEmail)) { ModelState.AddModelError("", "用户邮箱不能为空"); return BadRequest(ModelState); } application.Status = Status.Incomplete; application.ApplicationType = "Premature Ejaculation"; application.FlowId = await _applicationManagementService.Create(application); }添加模型验证日志:在
OnPostSubmitAsync开头添加验证检查,明确错误原因:public async Task<IActionResult> OnPostSubmitAsync(FEApplication? application) { if(!ModelState.IsValid) { var errors = ModelState.Values.SelectMany(v => v.Errors).Select(e => e.ErrorMessage); return BadRequest(string.Join(";", errors)); } // 原有逻辑... }前端确保提交数据完整性:确认
#ApplicationData表单包含UserEmail等必填字段,避免提交空值。
内容的提问来源于stack exchange,提问作者IR'Shah
相关产品推荐
相关产品推荐

