I’m designing forms in my ASP.NET MVC application that will receive objects. Here’s what a typical edit action looks like:
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(int id, Person person) { peopleService.SavePerson(person); return Redirect('~/People/Index'); }
The SavePerson call in the service does this:
public void SavePerson(Person person) { _peopleRepository.SavePerson(person); }
And the SavePerson call in the repository does this:
public void SavePerson(Person person) { using (var dc = new SIGAPDataContext()) { if (person.IsNew) { dc.People.InsertOnSubmit(person); } else { dc.People.Attach(person, true); } dc.SubmitChanges(); } }
Now, this works well when I create the new record. However, when I update it without all the form elements, it nulls other fields. For instance, my Person model has a NationalityID property that is nulled if it doesn’t show on the edit form.
What’s the best practice to make the model update with just the fields that come from the form? Do I have to get the record from the database first and update it’s properties manually like:
Person persistedPerson = peopleService.GetPerson(person.ID); persistedPerson.Name = person.Name; persistedPerson.DateOfBirth = person.DateOfBirth // etc...
Or is there any other, cleaner way to do this?
In your controller, retrieve the existing person from the repository, then use UpdateModel/TryUpdateModel and pass in a whitelist of properties that you want to be updated. This would use the ValueProvider on the controller so there is no need to take the Person object in the action parameter list.