MVC3 with EF 4.1 and EntityState.Modified on update
I'm having problems understanding EntityState.Modified when it comes to updating an object with .NET MVC3.
I have a model that stores an ImageFilePath and ImageContentType when an image is uploaded. Here is what the create action looks like.
[HttpPost]
public ActionResult Create(SneakPeekCollection collection, HttpPostedFileBase image)
{
try
{
if (image != null)
{
var filepath = Path.Combine(HttpContext.Server.MapPath("../../Uploads"), Path.GetFileName(image.FileName));
image.SaveAs(filepath);
collection.ImageContentType = image.ContentType;
collection.ImageFilePath = "~/Uploads/" + image.FileName;
}
_db.SneakPeekCollections.Add(collection);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
The problem comes when trying to edit and subsequently update this object. This is my Edit action.
[HttpPost]
public ActionResult Edit(int id, SneakPeekCollection collection, HttpPostedFileBase image)
{
try
{
if (image != null)
{
var filepath = Path.Combine(HttpContext.Server.MapPath("../../../Uploads"), Path.GetFileName(image.FileName));
image.SaveAs(filepath);
collection.ImageContentType = image.ContentType;
collection.ImageFilePath = "~/Uploads/" + image.FileName;
}
_db.Entry(开发者_JAVA百科collection).State = EntityState.Modified;
_db.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
I believe the problem comes from the fact that I'm setting EntityState.Modified which marks all properties as modified. If I don't upload a new image, the ImageFilePath and ImageContentType coming from the front-end are effectively null which is what is getting stored.
My question is how do I resolve this? What is the proper way to use EntityState.Modified?
Instead of using implicit model binding by accepting a SneakPeakCollection in your parameters, you could retrieve the model from the db and use UpdateModel to get the new values if they exist. Something like this:
var collection = _db.SneakPeaks.Find(id); // Get the entity to update from the db
UpdateModel(collection); // Explicitly invoke model binding
if (image != null)
{
var filepath = Path.Combine(HttpContext.Server.MapPath("../../../Uploads"), Path.GetFileName(image.FileName));
image.SaveAs(filepath);
collection.ImageContentType = image.ContentType;
collection.ImageFilePath = "~/Uploads/" + image.FileName;
}
_db.SaveChanges();
On your submit you need to check whether model is valid, and then run your CRUD routines.
if(ModelState.IsValid)
{
// Save my model
}
The complete info you can find here http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx
精彩评论