Detect state change of model property, in controller, using Entity Framework

asp.net-mvc asp.net-mvc-3 entity-framework

Question

I have a more or less standard looking model:

public class Project {
  public int ID { get; set; }
  //... some more properties

  public DateTime StartDate { get; set; }
  public int Duration { get; set; }
}

If the user modifies StartDate or project Duration, I have to call a function to update a simulation. In order to achieve this I'd like to detect the state change of the fields StartDate and Duration within a controller.

Something like that:

if(project.StartDate.stateChange() || project.Duration.stateChange())

Here is an example of what the Controller Method would look like:

[HttpPost]
public ActionResult Edit(Project project)
{
    if (ModelState.IsValid)
    {
        if(project.StartDate.stateChange() || project.Duration.stateChange())
            doSomething();

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

Any idea, how can I achieve this?

1
7
6/20/2014 1:10:49 PM

Accepted Answer

I believe you can compare the edited entity with the original one read from the database.

Something like:

public ActionResult Edit(Project project)
{
    if (ModelState.IsValid)
    {
        var original = db.Find(project.ID);
        bool changed = original.StartDate != project.StartDate || original.Duration != project.Duration;
        if (changed)
        {
            original.StartDate = project.StartDate;
            original.Duration = project.Duration;
            doSomething();
            db.Entry(original).CurrentValues.SetValues(project);
            db.SaveChanges();
        }
    }
    return View(project);
}
9
6/15/2018 10:43:07 AM

Popular Answer

You can solve it by carrying old values via ViewBag.

In action:

public ActionResult Edit(int? id)
{
    //...Your Code
    ViewBag.OrigStartDate = project.StartDate;
    ViewBag.OrigDuration = project.Duration;
    return View(project);
}

Add hidden elements to View

...
@Html.Hidden("OrigStartDate", (DateTime)ViewBag.OrigStartDate)
@Html.Hidden("OrigDuration", (int)ViewBag.OrigDuration)
...

Add these parameters to the post method and check them for changes

[HttpPost]
public ActionResult Edit(DateTime OrigStartDate, int OrigDuration)
{
    if (ModelState.IsValid)
    {
        if (OrigStartDate != project.StartDate || OrigDuration != project.Duration)
            doSomething();

        db.Entry(project).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    ViewBag.FileTypeId = new SelectList(db.FileTypes, "Id", "TypeName", dbinfo.FileTypeId);
    return View(project);
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow