ASP.NET Core表单双按钮验证:忽略必填项实现保存进度
实现ASP.NET Core表单的“保存进度”与“完整提交”双按钮验证
嘿,这个需求我之前在项目里刚好折腾过,结合ASP.NET Core自带的jquery-validation-unobtrusive和视图模型验证,完全可以搞定,给你一步步拆解:
1. 视图层:添加区分按钮
首先在表单里放两个提交按钮,通过name和value来区分它们的动作,这样后端和前端都能识别:
<form asp-action="HandleForm" method="post"> <!-- 示例表单字段,带验证特性 --> <div class="form-group"> <label asp-for="FullName"></label> <input asp-for="FullName" class="form-control" /> <span asp-validation-for="FullName" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Email"></label> <input asp-for="Email" class="form-control" /> <span asp-validation-for="Email" class="text-danger"></span> </div> <div class="form-group"> <label asp-for="Notes"></label> <textarea asp-for="Notes" class="form-control"></textarea> <span asp-validation-for="Notes" class="text-danger"></span> </div> <!-- 两个提交按钮 --> <button type="submit" name="formAction" value="SaveProgress" class="btn btn-outline-secondary">保存进度</button> <button type="submit" name="formAction" value="Submit" class="btn btn-primary">提交表单</button> </form>
2. 前端JS:拦截提交,动态调整验证规则
核心思路是:当点击「保存进度」时,临时移除所有必填字段的验证规则,执行验证后再恢复规则,这样既保留了非必填字段的格式验证(比如邮箱格式),又跳过了必填项检查。
$(function () { const $form = $('form'); // 拦截表单提交事件 $form.on('submit', function (e) { // 找到触发提交的按钮(解决按钮未聚焦的情况,也可以用document.activeElement) const $clickedBtn = $(document.activeElement); const isSaveProgress = $clickedBtn.val() === 'SaveProgress'; if (isSaveProgress) { // 1. 保存所有必填字段的原始验证规则 $form.find('[data-val-required]').each(function () { const $input = $(this); $input.data('originalValidationRules', $input.rules()); // 移除必填验证规则 $input.rules('remove', 'required'); }); // 2. 执行当前规则下的验证 const isValid = $form.valid(); // 3. 恢复所有必填字段的原始验证规则,避免影响后续提交 $form.find('[data-val-required]').each(function () { const $input = $(this); const originalRules = $input.data('originalValidationRules'); if (originalRules) { $input.rules('add', originalRules); } }); // 如果验证不通过,阻止表单提交 if (!isValid) { e.preventDefault(); return false; } } // 「提交表单」按钮就用默认的完整验证,无需额外处理 }); });
3. 后端Action:区分处理逻辑
在控制器里,通过按钮的value来判断是保存进度还是完整提交,分别处理:
[HttpPost] public IActionResult HandleForm(YourFormViewModel model, string formAction) { if (formAction == "SaveProgress") { // 这里的ModelState已经排除了必填项的错误(前端已经处理) // 只需要处理其他验证错误(比如邮箱格式) if (ModelState.IsValid) { // 保存进度逻辑:比如存入数据库草稿表、Session或者本地存储 TempData["SuccessMessage"] = "表单进度已保存!"; return RedirectToAction(nameof(YourFormPage)); } // 验证不通过,返回视图显示错误 return View(model); } else if (formAction == "Submit") { // 完整验证:默认会检查所有[Required]等特性 if (ModelState.IsValid) { // 处理正式提交逻辑 return RedirectToAction(nameof(SubmitSuccess)); } return View(model); } return BadRequest("无效的操作"); }
一些注意事项
- 确保你的视图模型字段上的
[Required]特性正确,这样jquery-validation-unobtrusive才会生成data-val-required属性,前端才能识别必填字段。 - 如果有自定义验证特性(比如
[Phone]),这些在保存进度时依然会生效,符合需求里的「验证字段但忽略必填项」。 - 如果你不想用按钮value判断,也可以给按钮加自定义data属性(比如
data-action="save-progress"),然后在JS里判断$clickedBtn.data('action') === 'save-progress',更灵活。
内容的提问来源于stack exchange,提问作者Tim Long
相关产品推荐
相关产品推荐

