ASP.NET Web应用表单提交验证失败时跳转空白页问题排查
ASP.NET Web应用表单验证问题排查
我的ASP.NET Web应用中,提交表单时输入信息正确的话,TimeCard可以正常更新;取消表单能正常返回且无变更。系统已设置验证规则确保时间和Comment字段不为空,但当Comment字段留空时,页面会跳转到空白页。该功能此前正常,近期整理代码后出现此问题,排查Git提交记录未发现相关代码变更。
TimeCard实体
public class TimeCard { // 由数据库设置 public int Id { get; set; } public DateTime ClockIn { get; set; } = DateTime.Today; public DateTime ClockOut { get; set; } = DateTime.MinValue; public bool IsIn { get; set; } public bool Sickness { get; set; } public bool Holiday { get; set; } // 用于批量添加多天假期 [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] [DataType(DataType.Date)] public DateTime HolidayStartDate { get; set; } [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)] [DataType(DataType.Date)] public DateTime HolidayEndDate { get; set; } // 并非始终必填,仅在创建和编辑工时卡时需要 [StringLength(100, MinimumLength = 5)] public string Comment { get; set; } // 工时卡属于用户(员工) public int UserId { get; set; } // 外键 public User User { get; set; } // 导航属性 }
编辑视图页面
@model TimeCard <h3 class="Form-heading">编辑工时卡</h3> <form asp-action="EditTimeCard" method="post" onsubmit="combineDateTime()"> <input type="hidden" asp-for="Id" /> <!-- 用于存储合并后DateTime值的隐藏字段 --> <input type="hidden" id="ClockIn" asp-for="ClockIn" /> <input type="hidden" id="ClockOut" asp-for="ClockOut" /> <div class="row"> <div class="col-md-6"> <div class="form-group edit-form"> <label class="form-label"><i class="bi bi-calendar-plus-fill"></i>日期</label> <input type="date" id="ClockInDate" class="form-control" /> </div> </div> <div class="col-md-6"> <div class="form-group edit-form"> <label class="form-label"><i class="bi bi-alarm-fill"></i>上班时间</label> <input type="time" id="ClockInTime" class="form-control" /> </div> <div class="form-group edit-form"> <label class="form-label"><i class="bi bi-alarm-fill"></i>下班时间</label> <input type="time" id="ClockOutTime" class="form-control" /> </div> </div> </div> <div class="form-group edit-form"> <label asp-for="Comment" class="form-label">备注</label> <input type="text" asp-for="Comment" class="form-control" /> <span asp-validation-for="Comment" class="text-danger"></span> </div> <button type="submit" class="btn1">编辑工时卡</button> <a class="cancel-btn" asp-controller="User" asp-action="TimeCardLog" asp-route-id="@Model.User.Id">取消</a> </form> <script> document.addEventListener("DOMContentLoaded", function () { var clockIn = new Date('@Model.ClockIn.ToString("o")'); var clockOut = new Date('@Model.ClockOut.ToString("o")'); document.getElementById('ClockInDate').value = clockIn.toISOString().split('T')[0]; document.getElementById('ClockInTime').value = clockIn.toTimeString().split(' ')[0].substring(0, 5); document.getElementById('ClockOutTime').value = clockOut.toTimeString().split(' ')[0].substring(0, 5); }); function combineDateTime() { var clockInDate = document.getElementById('ClockInDate').value; var clockInTime = document.getElementById('ClockInTime').value; var clockOutTime = document.getElementById('ClockOutTime').value; var clockInDateTime = clockInDate + 'T' + clockInTime; document.getElementById('ClockIn').value = clockInDateTime; var clockOutDateTime = clockInDate + 'T' + clockOutTime; document.getElementById('ClockOut').value = clockOutDateTime; } </script>
编辑功能控制器
// GET: /User/EditTimeCard/{id} [Authorize(Roles = "manager, admin")] public IActionResult EditTimeCard(int id) { var timeCard = _tcSvc.GetTimeCard(id); if (timeCard == null) { Alert($"未找到工时卡", AlertType.warning); return RedirectToAction("TimeCardLog", new { id = timeCard.UserId }); } return View(timeCard); } // POST: /User/EditTimeCard/{id} [HttpPost] public IActionResult EditTimeCard(int id, TimeCard model) { if (string.IsNullOrWhiteSpace(model.Comment)) { ModelState.AddModelError("Comment", "备注不能为空,请输入编辑原因"); } if (ModelState.IsValid) { var updatedTimeCard = _tcSvc.UpdateTimeCard(id, model.ClockIn, model.ClockOut, model.Comment); if (updatedTimeCard != null) { Alert("工时卡更新成功", AlertType.success); return RedirectToAction("TimeCardLog", new { id = updatedTimeCard.UserId }); } else { Alert("工时卡无法更新", AlertType.warning); } } return View(model); }
已尝试的操作
已添加以下验证脚本,但问题仍未解决。添加TimeCard的表单验证功能正常。
@section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } }
排查思路
- 检查视图数据完整性:当Comment为空导致ModelState无效时,返回
View(model)需确认model.User是否为null。视图中使用了@Model.User.Id,若User导航属性未被正确填充,会抛出空引用异常导致页面空白。可在POST方法返回视图前,手动从服务获取包含User信息的完整TimeCard数据再传递给视图。 - 前端提交流程验证:检查
combineDateTime函数是否拦截了表单默认验证。可修改为onsubmit="return combineDateTime();"并在函数末尾添加return true;,确保前端验证能正常触发。 - 客户端验证有效性:打开浏览器开发者工具,确认Comment为空时是否触发前端验证拦截提交。若未触发,检查
_ValidationScriptsPartial是否包含正确的jQuery Validation和Unobtrusive Validation脚本,且页面是否正确加载这些脚本。 - 后端异常捕获:在POST方法中添加
try-catch块,排查是否有未处理的异常。例如model.User为空时,渲染@Model.User.Id会抛出异常,可在返回视图前设置model.User = _userSvc.GetUser(model.UserId);确保User属性不为空。 - 布局页脚本渲染检查:确认布局页中是否正确包含
@RenderSection("Scripts", required: false),若Scripts区块未被正确渲染,验证脚本无法加载会导致前端验证失效,进而引发后端返回视图时的空白问题。
内容的提问来源于stack exchange,提问作者molly1312
相关产品推荐
相关产品推荐

