MVC使用Controller中的TryUpdateModel检查表单中的模型值

时间:2016-11-10 16:33:42

标签: c# asp.net-mvc updatemodel

我目前正在关注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的白名单将更容易和更安全,我正在努力掌握如何从表单中访问返回到控制器的数据。

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

感谢所有帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

这不是答案。

The Microsoft tutorial is here(免责声明我与詹姆斯合作并要求他通过发布问题来学习。)

并在下面写下有关为什么我们不应该使用詹姆斯已经链接的原始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标志会使Entity Framework创建SQL语句以更新数据库行。忽略并发冲突,并更新数据库行的所有列,包括用户未更改的那些列。 (后面的教程展示了如何处理并发冲突,如果您只想在数据库中更新单个字段,则可以将实体设置为Unchanged并将各个字段设置为Modified。)

作为防止叠加的最佳做法,您希望通过“编辑”页面更新的字段在TryUpdateModel参数中列入白名单。目前没有您需要保护的额外字段,但列出您希望模型绑定器绑定的字段可确保如果您将来向数据模型添加字段,它们将自动受到保护,直到您明确将它们添加到这里。

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