BryanP
BryanP

Reputation: 330

Update object from the view inside the controller

I'm trying to make changes to an object that my controller is getting back from the view. When I debug and step through the program and look at the values of job.JobTypesId and job.JobStatusID the correct values are displaying but they are not being saved while everything else does. I have read a couple of articles that explain that the framework needs to know that the model has changed and that's what the entity state is supposed to do (http://www.mattburkedev.com/saving-changes-with-entity-framework-6-in-asp-dot-net-mvc-5/). I have also tried to use UpdateModel but that dosent seem to work either (http://forums.asp.net/t/1807184.aspx?MVC+4+Not+saving+data+after+edit). I get a message "The model of type 'StaffServiceTracker.Models.Job' could not be updated.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Job job) {

      var task = from t in db.JobTypes where t.JobTypeID == job.JobTypesID.JobTypeID select t;

      var status = from s in db.Statuses
      where s.StatusID == job.JobStatusID.StatusID
       select s;

      job.JobTypesID = task.FirstOrDefault();

     job.JobStatusID = status.FirstOrDefault();

     db.Entry(job).State = EntityState.Modified;
     db.SaveChanges();
     return RedirectToAction("Index");
 }

Any guidance would be appreciated.

Upvotes: 1

Views: 403

Answers (1)

Francisco Goldenstein
Francisco Goldenstein

Reputation: 13767

First of all, you should use ViewModels (in 90% of the cases) instead of business objects in the views. This is because you would send only the necessary data to the client, you can combine business objects, etc.

Second, once you receive the ViewModel in the controller you should first validate it (always validate at client and server side because client side validations can be bypassed).

Once you have validated everything, get the Job object from the database using EF and set the properties. Call SaveChanges and that's it. It would be better if you move this code from the controller to the service layer.

One more thing: you can use SQL Server Profiler to know exactly what queries EF is executing. That way you'll understand what's happening.

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(JobVM jobVM) {

      // validate VM
      // ...
      // the following code should be in the Service Layer but I'll write it below to simplify
      // get job from DB
      var job = db.Jobs.SingleOrDefault(p => p.Id == jobVM.Id);

      job.JobTypesID = jobVM.JobTypesID;

      job.JobStatusID = jobVM.StatusId;

      db.SaveChanges();
      return RedirectToAction("Index");
 }

Upvotes: 2

Related Questions