qakmak qakmak - 2 months ago 20
C# Question

How keep original value for some field when execute Edit on MVC?

As you know, When we want to Modify a data, We will go to Edit page:

public ActionResult EditAdmin(int UserId)
{
User user = persons.Users.Find(id);
return View(user);
}


Then We submit it on the Edit Page, it will Modify:

public ActionResult EditAdmin(User user)
{
persons.Entry(user).State = EntityState.Modified;
persons.SaveChanges();
}


But the problem is , I have alot of field don't need be modify:

public class User{
public int UserId {get; set;} // do not need modify
public int Password {get; set;} // do not need modify
public string Name {get; set;}
public bool Sex {get; set;}
public DateTime AddTime {get; set;} // do not need modify
}


Obviously, I can't display some field on my edit page use Hidden, because I don't want it display on UI. but when submit, I still need it still keep the original value. So Is there any good idea for it? Thanks

Update1:

Why I can't use like

entry.Property(e => e.Password).IsModified = false;


link: http://stackoverflow.com/a/18004476/1900498

But It will display :


Validation failed for one or more entities. See
'EntityValidationErrors' property for more details.

Answer

Fetch the existing version from the database, and then change just the 'modifiable' fields:

public ActionResult EditAdmin(User user)
{ 
    var currentPerson = db.Persons.FirstOrDefault(p => p.id = user.id);
    if (currentPerson == null)
        return HttpNotFound();

    currentPerson.Name = user.Name;
    currentPerson.Sex = user.Sex;
    // Id and Password are not updated.

    db.SaveChanges();
}
  • You might also want to do some optimistic concurrency checking as well, to ensure that the version being updated, is in fact current. Ideally, if you have a timestamp, use this, otherwise, you are faced with comparing all fields.

Edit
See also @Kris' comment and Ric's point about creating tailored view models and hence NOT polluting your views with ORM / data tier entities. I also still contend you need to carry a timestamp or hash through the ViewModel to prevent the last one wins overwriting problem.