Every article found in the Internet on using ViewModels and utilizing Automapper gives the guidelines of the "Controller -> View" direction mapping. You take a domain model along with all Select Lists into one specialized ViewModel and pass it to the view. That's clear and fine.
The view has a form, and eventually we are in the POST action. Here all the Model Binders come to the scene along with [obviously] another View Model which is [obviously] related to the original ViewModel at least in the part of naming conventions for the sake of binding and validation.
How do you map it to your Domain Model?
Let it be an insert action, we could use the same Automapper. But what if it was an update action? We have to retrieve our Domain Entity from the Repository, update it's properties according to the values in the ViewModel and save to the Repository.
ADDENDUM 1 (9th of February 2010): Sometimes, assigning Model's properties is not enough. There should be taken some action against Domain Model according to the values of View Model. I.e., some methods should be called on Domain Model. Probably, there should be a kind of an Application Service layer which stands between Controller and Domain in order to process View Models...
How to organize this code and where to place it to achieve the following goals?
I use an IBuilder interface and implement it using the ValueInjecter
public interface IBuilder<TEntity, TViewModel> { TEntity BuildEntity(TViewModel viewModel); TViewModel BuildViewModel(TEntity entity); TViewModel RebuildViewModel(TViewModel viewModel); }
... (implementation) RebuildViewModel just calls BuildViewModel(BuilEntity(viewModel))
[HttpPost] public ActionResult Update(ViewModel model) { if(!ModelState.IsValid) { return View(builder.RebuildViewModel(model); } service.SaveOrUpdate(builder.BuildEntity(model)); return RedirectToAction("Index"); }
btw I don't write ViewModel I write Input cuz it's much shorter, but that just not really important
hope it helps
Update: I'm using this approach now in the ProDinner ASP.net MVC Demo App, it's called IMapper now, there's also a pdf provided where this approach is explained in detail
Tools like AutoMapper can be used to update existing object with data from source object. The controller action for updating might look like:
[HttpPost] public ActionResult Update(MyViewModel viewModel) { MyDataModel dataModel = this.DataRepository.GetMyData(viewModel.Id); Mapper<MyViewModel, MyDataModel>(viewModel, dataModel); this.Repostitory.SaveMyData(dataModel); return View(viewModel); }
Apart from what is visible in the snippet above:
Controller action is pretty thin and concerns are separated: mapping issues are addressed in AutoMapper configuration, validation is done by ModelBinder and data access by Repository.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With