ASP.NET MVC UpdateModel()方法如何工作?

Kir*_*ein 29 asp.net-mvc

我正在研究我的第一个.NET MVC应用程序并使用NerdDinner教程作为参考点.目前令我着迷的一点是UpdateModel()方法.(我不喜欢使用我不太懂的东西.)

取自NerdDinner教程 -

//
// 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 });
}
Run Code Online (Sandbox Code Playgroud)

我的主要问题是如何UpdateModel()在Edit方法中传递对formValues的访问权限?为什么集合没有作为参数显式传递给方法?

小智 28

UpdateModel()是一个Controller辅助方法,它尝试将一堆不同的输入数据源(来自View,QueryString值,会话变量/ Cookie等的HTTP POST数据)绑定到您指定为参数的显式模型对象.从本质上讲,它仅适用于模型绑定.

如果将Action的输入参数表示为强类型模型(如视图模型),则在调用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 });
}
Run Code Online (Sandbox Code Playgroud)

但是,有一个用例,用于将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 });
}
Run Code Online (Sandbox Code Playgroud)

这里唯一的优点(使用FormCollection对象)是您可以访问强类型对象的所有其他属性(如incoming.DinnerID所示).

结论:如果要将强类型对象转换为派生对象,则最简单的方法是使用UpdateModel().但是,如果只是更新派生对象的一些属性,则基本上没有必要.此外,请注意使用实体框架(而不是Linq to SQL之类的东西)会使所有这些都没有用,因为它可以将强类型对象和派生对象与自己的方法联系起来.


And*_*nea 4

它确实检查所有 HttpRequest 输入,例如表单、查询字符串、Cookie 和服务器变量。我想按照这个顺序。