我正在开发我的第一个.NET MVC应用程序,并使用NerdDinner教程作为参考点。目前有趣的一点是UpdateModel()方法。 (我不喜欢使用我不太明白的东西。)
// // POST: /Dinners/Edit/2 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(int id,FormCollection formValues) { Dinner dinner = dinnerRepository.GetDinner(id); UpdateModel(dinner); dinnerRepository.Save(); return RedirectToAction("Details",new { id = dinner.DinnerID }); }
我的主要问题是UpdateModel()如何访问在Edit方法中传递的formValues?为什么集合不会作为参数显式传递给方法?
解决方法
UpdateModel()是一个Controller helper方法,它尝试将一堆不同的输入数据源(来自View,QueryString值,Session变量/ Cookies等的HTTP POST数据)绑定到指定为参数的显式模型对象。实质上,它只适用于模型绑定。
如果您将Action的输入参数表示为强类型模型(如View Model),那么在UpdateModel()被调用时,您已经执行了幕后完成的所有步骤。如果从DataContext检索对象并编辑其属性,则SaveChanges()就是将更新推送回数据库所需的全部(在本例中为Save())。
例:
// // POST: /Dinners/Edit/2 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Dinnerviewmodel incoming) { var dinner = dinnerRepository.GetDinner(incoming.DinnerID); dinner.Description = incoming.Description; dinnerRepository.Save(); return RedirectToAction("Details",new { id = incoming.DinnerID }); }
但是,使用UpdateModel()与强类型模型有一个用例:当您传递强类型模型并希望其值直接从数据库中替换实体时(如果它们都命名为并键入相同)。在这种情况下,您将检索该对象,对其使用UpdateModel(),其模型绑定操作将从强类型对象中引入任何类似命名和类型的属性到检索对象。换句话说,它会为你做反思。
所以,像你的例子一样,如果你希望所有属性都更新而不指定要更新的内容,而强类型的模型和数据库模型具有类似命名的属性,你仍然希望使用UpdateModel()来利用反射。
例:
// // POST: /Dinners/Edit/2 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Dinnerviewmodel incoming) { var dinner = dinnerRepository.GetDinner(incoming.DinnerID); UpdateModel(dinner); dinnerRepository.Save(); return RedirectToAction("Details",new { id = incoming.DinnerID }); }
这里唯一的优点(使用FormCollection对象)是您可以访问强类型对象的所有其他属性(如incoming.DinnerID所示)。
结论:如果您将一个强类型的对象转换为派生对象,那么最简单的方法是使用UpdateModel()。但是,如果您仅仅是更新派生对象的几个属性,则很大程度上是不必要的。另外,请注意,使用实体框架(而不是类似Linq to sql)可以使所有这些模糊,因为它可以使用自己的方法来连接强类型的对象和派生对象。