ASP.NET MVC修改预订表数据state字段不更新及发邮件报错如何解决
问题1:state字段修改后后端接收不到值
原因
控制器Action的[Bind]特性的Include白名单未包含state字段,ASP.NET MVC模型绑定会直接过滤白名单外的字段,所以无论前端怎么修改,后端拿到的reserv.state都是默认值。
解决方法
将state和后续发邮件需要用到的ClientMail都加入Bind的Include列表:
[HttpPost] public ActionResult GérantRéservationApprove([Bind(Include = "reservation_id, date, nb_persons, RestoId, state, ClientMail")] Reservation reserv)
问题2:执行时报错System.InvalidOperationException : 'Un destinataire doit être spécifié.'
原因
和第一个问题根源一致:ClientMail也不在Bind白名单内,后端拿到的reserv.ClientMail为null,调用WebMail.Send时第一个参数收件人为空,就抛出了这个异常,异常的法语含义为「必须指定收件人」。
完成上一步修改,把ClientMail加入Bind白名单即可解决该问题。
安全性优化建议
你当前直接将整个实体标记为EntityState.Modified的写法,会把所有绑定的字段都更新到数据库,即使前端加了readonly属性,也无法防止恶意用户构造请求篡改其他字段的值,更安全的写法是按ID查询原有记录,仅更新需要修改的state字段:
[HttpPost] public ActionResult GérantRéservationApprove([Bind(Include = "reservation_id, state")] Reservation reserv) { if (ModelState.IsValid) { // 从数据库查询原有完整记录 var existReserv = db.Reservation.FirstOrDefault(r => r.reservation_id == reserv.reservation_id); if(existReserv == null) return RedirectToAction("GérantRéservation", "Admin"); // 仅更新允许修改的state字段 existReserv.state = reserv.state; string objet, contenu; if (existReserv.state == false) { objet = "预订不可用"; contenu = $"尊敬的客户您好,我们很抱歉地通知您,您预订的{existReserv.date}的席位暂时无法安排,敬请谅解。"; } else { objet = "预订确认"; contenu = $"尊敬的客户您好,您{existReserv.date}的预订已审核通过,感谢您选择我们餐厅。"; } // 使用数据库存储的邮箱发信,避免被用户篡改 WebMail.Send(existReserv.ClientMail, objet, contenu, null, null, null, false, null, null, null, null, null, null); db.SaveChanges(); return RedirectToAction("GérantRéservation", "Admin"); } return RedirectToAction("GérantRéservation", "Admin"); }
该写法不需要把其他字段加入Bind白名单,也完全避免了用户篡改邮箱、预订日期、人数等敏感数据的风险。
内容的提问来源于stack exchange,提问作者user15597443
相关产品推荐
相关产品推荐

