When editing an object (like an entity) in MVC, it returns a new one populated with your objects. If you try to save it using dataContext.Attach(), you may find that when saving it bombs on you. A great example of this would be something like a DateTime called .CreatedOn, since you wouldn’t let users edit it, would be the same value as new DateTime() which is year 0 or 1. When the object attempts to be persisted it won’t allow a date that low to be stored in a normal datetime field in SQL (datetime2, yes, but datetime should be sufficient in most cases) and bombs with a YSOD.
Maybe there’s a better way, but until I discover it or someone points it out to me, here’s what I did:
/// <summary> /// Maps only the submitted changes in model state from one object to another. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="mapToObject"></param> /// <param name="mapFromObject"></param> public static void MapChangedProperties<T>(this ModelStateDictionary modelState, ref T mapToObject, T mapFromObject) { var props = typeof(T).GetProperties(); foreach (var item in modelState) { var prop = props.FirstOrDefault(p => p.Name == item.Key); if (prop != null) { prop.SetValue(mapToObject, prop.GetValue(mapFromObject, null), null); } } }
To use, get the object out of the database and run this on it:
// "obj" is our returned model name, and we have a database connection open if (ModelState.IsValid) { dbObj = db.Objs.Single(o => o.ID = obj.ID); ModelState.MapChangedProperties(ref dbObj, obj); dbObj.ModifiedDT = DateTime.UtcNow; db.SaveChanges(); }