在控制器中使用TryUpdateModel检查表单中的模型值

本文关键字:表单 模型 检查表 TryUpdateModel 控制器 检查 | 更新日期: 2023-09-27 18:17:31

我目前正在学习MVC 5的教程,我被困在如何对用户输入的字段执行验证检查而不绑定编辑方法中的字段。

我已经有了一个编辑页面,但它在开始时绑定了所有字段-我遵循的教程清楚地表明,我不应该这样做。

我的原始代码如下。因为我在开始时绑定了所有字段,所以我可以通过使用货车来执行检查。fieldname如下所示,'if (vans。AssetID == 20)'

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit([Bind(Include = "AssetID,Batch_Number,Customer_Account_Holder,Dealer_ID, ")] Vans__ vans)
    {
        if (vans.AssetID == 20) //Example - check if data entered for AssetID is 20
        {
          //do something
        }
        if (ModelState.IsValid)
        {
            db.Entry(vans__).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(vans__);
    }

在我所遵循的教程中,我被指示不要在开始时绑定所有内容,而是使用如下代码:

    public ActionResult EditPost(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        //In here vans is the original values and not from the form.
        Vans__ vans = db.Vans__.Find(id);
       //Here how can I check if AssetID is a certain number returned from the form?
        if (TryUpdateModel(vans, "", new string[] { "AssetID" }))
        {
            try
            {
                db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
    }

我理解使用TryUpdateModel的白名单将更加容易和安全,我只是在努力掌握如何访问从表单返回给控制器的数据。

我如何访问模型,以便我添加我自己的验证检查?

感谢所有的帮助,谢谢。

在控制器中使用TryUpdateModel检查表单中的模型值

这不是答案。

微软教程在这里(免责声明我和詹姆斯一起工作,并要求他通过发布问题来学习)。

并从下面写为什么我们不应该使用James链接的原始BIND方法。

[HttpPost, ActionName("Edit")]
[ValidateAntiForgeryToken]
public ActionResult EditPost(int? id)
{
  if (id == null)
  {
    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
  }
  var studentToUpdate = db.Students.Find(id);
  if (TryUpdateModel(studentToUpdate, "",
   new string[] { "LastName", "FirstMidName", "EnrollmentDate" }))
  {
    try
    {
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    catch (DataException /* dex */)
    {
        //Log the error (uncomment dex variable name and add a line here to write a log.
        ModelState.AddModelError("", "Unable to save changes. Try again, and      if the problem persists, see your system administrator.");
    }
  }
  return View(studentToUpdate);
}

这些更改实现了防止重叠的安全最佳实践。脚手架生成了一个Bind属性,并将模型绑定器创建的实体添加到带有Modified标志的实体集中。不再推荐使用该代码,因为Bind属性会清除Include参数中未列出的字段中的任何预先存在的数据。将来,MVC控制器支架将被更新,这样它就不会为Edit方法生成Bind属性。

新代码读取现有实体并调用TryUpdateModel来更新用户输入的表单数据中的字段。实体框架的自动更改跟踪在实体上设置了Modified标志。当调用SaveChanges方法时,Modified标志会导致实体框架创建SQL语句来更新数据库行。忽略并发性冲突,更新数据库行的所有列,包括用户未更改的列。(后面的教程将展示如何处理并发冲突,如果您只希望更新数据库中的单个字段,则可以将实体设置为Unchanged,并将单个字段设置为Modified。)

作为防止重叠的最佳实践,您希望Edit页面可更新的字段在TryUpdateModel参数中被列入白名单。目前没有需要保护的额外字段,但是列出您希望模型绑定器绑定的字段可以确保如果您将来向数据模型添加字段,它们会自动受到保护,直到您在这里显式地添加它们。

作为这些更改的结果,HttpPost编辑方法的方法签名与HttpGet编辑方法相同;因此,您已将方法重命名为EditPost。