Reputation: 14868
I'm working on my first .NET MVC application and using the NerdDinner tutorial as a reference point. One point that is intriguing me at the moment is the UpdateModel()
method. (I don't like using things I don't really understand.)
Taken from the NerdDinner tutorial -
//
// 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 });
}
My main question is how does the UpdateModel()
get access to the formValues passed in the Edit method? Why is the collection not passed in explicitly as a parameter to the method?
Upvotes: 31
Views: 42043
Reputation: 11
Instead of passing Model object as a parameter to "Post()" action method, we are creating an instance of an Model object within the "Post()" function, and updating it using "UpdateModel()" function. "UpdateModel()" function inspects all the HttpRequest inputs such as posted Form data, QueryString, Cookies and Server variables and populate the employee object.
e.g.
[HttpPost]
[ActionName("Create")]
public ActionResult Create_Post()
{
EmployeeBusinessLayer employeeBusinessLayer =
new EmployeeBusinessLayer();
Employee employee = new Employee();
UpdateModel(employee);
employeeBusinessLayer.AddEmmployee(employee);
return RedirectToAction("Index");
}
Upvotes: 1
Reputation: 420
UpdateModel() is a Controller helper method that attempts to bind a bunch of different input data sources (HTTP POST data coming from a View, QueryString values, Session variables/Cookies, etc.) to the explicit model object you indicate as a parameter. Essentially, it is only for model binding.
If you express the input parameters for your Action as a strongly-typed model (like a View Model), you've already taken all of the steps that are done behind the scenes when UpdateModel() is called. If you retrieve an object from the DataContext and edit its properties, SaveChanges() is all you need to push the updates back to the database (in this case, Save()).
Example:
//
// 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 });
}
However, there is a use-case for using UpdateModel() with a strongly-typed model: when you are passing in a strongly-typed model and want its values to directly replace those of an entity from the database (provided they are all named and typed the same). In this case, you would retrieve the object, use UpdateModel() on it, and its model binding operation will pull in any similarly-named and typed properties from the strongly-typed object to the retrieved object. In other words, it will perform reflection for you.
So, like your example, if you want all properties to update without specifying which to update, and your strongly-typed model and database model have similarly-named properties, you would still want to use UpdateModel() to take advantage of the reflection.
Example:
//
// 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 });
}
The only advantage here (over using a FormCollection object) is that you'd have access to all other properties of the strongly-typed object (as shown by incoming.DinnerID).
Conclusion: if you're translating a strongly-typed object to a derived object, it's probably easiest to use UpdateModel(). However, it's largely unnecessary if you are simply updating a few properties of the derived object. Also, be aware that use of the Entity Framework (instead of something like Linq to SQL) makes all of this moot, as it can relate strongly-typed objects and derived objects with its own methods.
Upvotes: 32
Reputation: 20800
It does inspect all the HttpRequest inputs such as Form, QueryString, Cookies and Server variables. I think in this order.
Upvotes: 4