I use View Models to hand to my MVC views, nice and slim with little if any methods on them and I use a think ORM model that has all my business logic and is generated by my ORM (BLToolkit).
So the problem is I wanted to take the View Model and update the ORM model with the modified values from the post, kind of a reverse AutoMapper (or BLToolkit.Mapper).
So a ORM class like this;
public class Contact { public int Id { get; set; } public string Firstname { get; set; } public string Lastname { get; set; } // Loads of other properties }
And a View Model like this (note the type and name should be “EXACTLY” the same;
public class ContactModel { public int Id { get; set; } public string Firstname { get; set; } public string Lastname { get; set; } }
Then with this generic Extension method;
public static void MergeWith(this T1 primary, T2 secondary) { foreach (var pi in typeof(T2).GetProperties()) { var tpi = typeof(T1).GetProperties().Where(x => x.Name == pi.Name).FirstOrDefault(); if (tpi == null) { continue; } var priValue = tpi.GetGetMethod().Invoke(primary, null); var secValue = pi.GetGetMethod().Invoke(secondary, null); if (priValue == null || !priValue.Equals(secValue)) { tpi.GetSetMethod().Invoke(primary, new object[] { secValue }); } } }
So you make the magic in the Controller (for example) like this;
[Authorize] [HttpPost] [ValidateAntiForgeryToken] [ValidateInput(false)] public ActionResult EditContact(ContactModel model) Contact c = Repo.Get<Contact,long>(model.Id); c.MergeWith<Contact,ContactModel>(model); Repo.Update<Contact>(c); }
Yea its cheesy, but it works for me 😉
Enjoy!
In your extension method MergeWith, the syntax of the generic declaration is using a construct I haven’t seen before:
public static void MergeWith(this T1 primary, T2 secondary)
the t2=”” piece. What does that do? Thanks.
Its just a variable for the generic since I had two generics being passed in I used and .