使用仓储模式时如何校验模型参数Total是否大于等于TotalMonths
错误原因
- 控制器参数引用错误:方法接收的参数名为
budget,但代码中错误使用了未赋值的BudgetVM变量读取属性,该变量下的UnitPrice、Quantity均为值类型默认值0,计算出的TotalAmount自然为0。 - 表单提交字段缺失:视图的提交表单中仅包含12个月份的输入框和
BudgetId隐藏域,UnitPrice、Quantity等计算TotalAmount必须的字段没有随表单提交,ASP.NET Core模型绑定时会将这些未提交的值类型字段设为默认值0,导致计算结果始终为0。 - 校验逻辑写反:需求为校验
Total不超过TotalMonths时允许保存,但当前代码判断条件为Total >= budget.FBudget.TotalMonths,与需求完全相反。
解决方案
- 修正控制器参数引用:将代码中所有
BudgetVM替换为方法入参名budget,示例修正后代码如下:
[HttpPost] [ValidateAntiForgeryToken] public IActionResult EditMonthDetail(BudgetViewModel budget) { // 直接用入参读取属性 var total = budget.FBudget.TotalAmount; // 修正校验逻辑:不超过才允许保存 if (total <= budget.FBudget.TotalMonths) { _unitOfWork.Budget.EditMonthDetails(budget.FBudget); _unitOfWork.Save(); return RedirectToAction("Success"); } return RedirectToAction("FailedTotal"); }
- 视图补充必填隐藏字段:在表单内添加
UnitPrice、Quantity以及其他所有FBudget模型中必填且不需要用户修改的字段的隐藏域,确保模型绑定能拿到正确的值,示例:
<form method="post" asp-action="EditMonthDetail"> <!-- 原有隐藏域 --> <input type="hidden" asp-for="FBudget.BudgetId" /> <!-- 补充计算需要的字段隐藏域 --> <input type="hidden" asp-for="FBudget.UnitPrice" /> <input type="hidden" asp-for="FBudget.Quantity" /> <!-- 其他必填字段如Year、FreeOfCharge、Currency、各个外键ID等也要按需补充隐藏域 --> <!-- 原有月份输入框代码 --> </form>
- 安全优化方案(可选):如果担心前端隐藏域被篡改,可以在控制器中先通过
budget.FBudget.BudgetId从数据库查询原始的FBudget数据,再将前端提交的12个月份值更新到查询出来的实体中,用数据库中存储的UnitPrice、Quantity计算TotalAmount,避免前端数据被伪造。
内容的提问来源于stack exchange,提问作者chdev
相关产品推荐
相关产品推荐

