Razor Pages中如何在JS验证函数内调用asp-page-handler提交表单
问题原因
- Razor Page默认开启POST请求防伪验证,你的AJAX请求没有携带
RequestVerificationToken,请求直接被拦截返回400,无法进入Handler方法 - 你的验证函数执行完AJAX后没有返回值,submit按钮的点击事件会默认阻止表单提交,就算Handler没问题也不会触发正常的表单提交流程
- AJAX请求没有携带任何表单数据,后端无法绑定表单模型,就算进入方法也拿不到数据完成入库
- 后端Handler当前返回的是页面跳转或页面对象,不适应AJAX请求的处理逻辑
解决方案
优先推荐第一种方案,改动最小,不需要调整后端原有逻辑,也能兼容文件上传的场景
方案1:验证通过直接触发表单原生提交(推荐)
你本身使用的是submit类型按钮,不需要额外通过AJAX提交,只要客户端验证通过后允许表单原生提交即可完全匹配需求:
- 给form标签添加提交目标Handler属性,注意如果有文件上传要加
enctype属性
<form method="post" enctype="multipart/form-data" asp-page-handler="Submit"> <!-- 原有表单内容 --> </form>
- 修改客户端验证函数,验证通过返回true触发提交
function OnSubmitValidate() { var RequestType = document.getElementById("DrpDwnRequestType"); var RequestTypeValue = RequestType.options[RequestType.selectedIndex].value; if ((RequestTypeValue == "") || (RequestTypeValue == null)) { document.getElementById("ErrRequestType").innerHTML = "Please select Request Type"; return false; } // 验证通过,返回true让表单自动提交 return true; }
修改完成后,原有后端OnPostSubmitAsync逻辑不需要任何调整,表单数据、上传文件都会自动绑定到后端对应属性,执行完成后也会正常跳转到请求汇总页。
方案2:保持AJAX提交的修改方法
如果确实需要异步提交,可按以下方式调整代码:
- 前端验证函数修改为携带表单数据和防伪Token
function OnSubmitValidate() { var RequestType = document.getElementById("DrpDwnRequestType"); var RequestTypeValue = RequestType.options[RequestType.selectedIndex].value; if ((RequestTypeValue == "") || (RequestTypeValue == null)) { document.getElementById("ErrRequestType").innerHTML = "Please select Request Type"; return false; } // 构建包含所有表单数据和文件的FormData var form = document.querySelector('form'); var formData = new FormData(form); // 获取Razor Page自动生成的防伪Token var token = document.querySelector('input[name="__RequestVerificationToken"]').value; $.ajax({ type: 'POST', url: rootPath + "/RequestForm?handler=Submit", data: formData, contentType: false, processData: false, headers: { "RequestVerificationToken": token }, success: function(res) { if(res.success) { // 前端手动跳转页面 window.location.href = res.redirectUrl; } else { alert(res.msg); } } }); // 阻止表单默认提交 return false; }
- 后端Handler适配AJAX请求返回JSON格式
public async Task<IActionResult> OnPostSubmitAsync() { BillType = new SelectList(_context.BillType.OrderBy(e => e.ID), "BillTypes", "BillTypes"); var requestexist = await _context.RequestFormMaster.FirstOrDefaultAsync(c => c.RequestID == RequestFormMaster.RequestID); if (requestexist != null) { return new JsonResult(new {success = false, msg = "当前请求ID已存在"}); } RequestFormMaster.RequestID = RequestFormMaster.RequestID.Trim(); RequestFormMaster.LastModifiedBy = HttpContext.Session.GetString("firstname") + " " + HttpContext.Session.GetString("lastname"); RequestFormMaster.LastModifiedTimeStamp = DateTime.Now; _context.Entry(RequestFormMaster).State = EntityState.Added; await _context.SaveChangesAsync(); TempData["ReqSubmitted"] = "Submitted"; if (ReqSupportingFiles != null && ReqSupportingFiles.Count > 0) { int i = 0; foreach (IFormFile upload in ReqSupportingFiles) { i++; string ext = Path.GetExtension(upload.FileName).ToLower(); if (ext is ".ppt" or ".pptx" or ".xls" or ".xlsx") { var filesave = Path.Combine(_env.WebRootPath, "Documents", foldername, i + "_" + upload.FileName); using (var stream = System.IO.File.Create(filesave)) { await upload.CopyToAsync(stream); } } } } return new JsonResult(new {success = true, redirectUrl = Url.Page("/RequestSummary")}); }
内容的提问来源于stack exchange,提问作者Teena
相关产品推荐
相关产品推荐

