The model validation errors show the current values (from our previous save). A previously hidden check box Force Save is displayed. You can use the Home link to cancel out of your changes, or you can check the Force Save box and all your changes will be saved.
A best practice is to use a rowversion to detect concurrency exceptions. The Product table of the AdventureWorksLT database doesn't include a rowversion field, so I added one with the name seqNum. To enable concurrency checking in the data model, open the EF model file (in my sample ProductsModel.edmx), right click the seqNum property of the Products entity and then click Properties. In the Properties window, change the ConcurrencyMode property to Fixed.
The following code will detect and handle concurrency conflicts:
[HttpPost] public ActionResult Edit(Product model) { try { if (!ModelState.IsValid) { return View(model); } db.Products.Attach(model); db.ObjectStateManager.ChangeObjectState(model, EntityState.Modified); db.SaveChanges(); return RedirectToAction("Details", new { id = model.ProductID }); } catch (OptimisticConcurrencyException ocex) { // Detach model to get current Product from DB db.Products.Detach(model); var cp = GetProduct(model.ProductID); AddModelErrors(cp, model); model.seqNum = cp.seqNum; ModelState.AddModelError("", "Optimistic Concurrency Exception occurred. Save Again to override"); } catch (Exception ex) { ModelState.AddModelError("", "See exception and inner exception"); } return View(model); }
When an optimistic concurrency exception is caught, the current data base values are fetched and displayed (when they differ with the current form values) as error messages. The current rowversion (sequence number) is also fetched so a subsequent save will persist to the DB in the absence of another change. If another user edits the row and saves it before you submit again, another optimistic concurrency exception will be detected.