How do bind my domain object Car to View?
MVC says "your class must have default constructor". But I don't want to change any business rules by creating a default constructor. The only solution I can see - is to use CarView in my View and then map it to Car.
P.S. NHibernate wants a default constructor too, but it can be protected. This I can do.
IMHO, its a good idea to seperate the objects that go to your view from you domain objects. This has a long list of advantages (which I am not going into now).
You can then use Automapper to map your view models to your domain objects
You could create the object yourself and call UpdateModel to do the binding instead:
public ActionResult MyAction()
{
var car = new MyCar(somethingToPassIntoTheConstructor);
UpdateModel(car);
// Do stuff with car.
}
Related
In an ASP.NET MVC project we are using AutoMapper to map from domain model to viewmodel - and sometimes also flattening a hierarchy while doing so. This works like a charm and makes the rendering logic of our views very lean and simple.
The confusion starts when we want to go the other way from viewmodel (or postmodel or editmodel) to domain model, especially when updating objects. We can't use automated/two-way mapping because:
we would have to unflat the flattened hierarchy
all properties on the domain model would have to be mutable/have public setters
the changes coming from the view isn't always just flat properties being mapped back to the domain, but sometimes need to call methods like "ChangeManagerForEmployee()" or similar.
This is also described in Jimmy Bogards article: The case for two-way
mapping in AutoMapper, but the solution to this isn't described in detail, only that they go:
From EditModel to CommandMessages – going from the loosely-typed
EditModel to strongly-typed, broken out messages. A single EditModel
might generate a half-dozen messages.
In a similar SO question there is an answer by Mark Seeman where he mentions that
We use abstract mappers and services to map a PostModel to a Domain Object
but the details - the conceptual and technical implementation - is left out.
Our idea right now is to:
Recieve a FormCollection in the controller's action method
Get the original domain model and flatten it to viewModelOriginal and viewModelUpdated
Merging the FormCollection into viewModelUpdated using UpdateModel()
Use some generic helper method to compare viewModelOriginal with viewModelUpdated
Either A) Generate CommandMessages a la Jimmy Bogard or B) Mutate the differences directly into the domain model through properties and methods (maybe mapping the 1-1 properties directly through AutoMapper)
Can someone provide some examples of how they come from FormCollection through editmodel/postmodel to domain model? "CommandMessages" or "abstract mappers and services"?
I use the following pattern:
[HttpPost]
public ActionResult Update(UpdateProductViewModel viewModel)
{
// fetch the domain model that we want to update
Product product = repository.Get(viewModel.Id);
// Use AutoMapper to update only the properties of this domain model
// that are also part of the view model and leave the other properties unchanged
AutoMapper.Map<UpdateProductViewModel, Product>(viewModel, product);
// Pass the domain model with updated properties to the DAL
repository.Update(product);
return RedirectToAction("Success");
}
You might want to consider CQRS(Command Query Responsibility Segregation - I think this might be the concept you were missing), possibly even with Event Sourcing.
It is basically a practice of separating the logic of reading from a data source and writing to a data source, might even mean having different data models for reading and writing.
This might be a good place to start: http://abdullin.com/cqrs/
Option C: Put it all in the controller action. Next, if that gets hairy, decompose into services (abstract mappers) or messages-as-methods (the command message way).
Command message way:
public ActionResult Save(FooSaveModel model) {
MessageBroker.Process(model);
return RedirectToAction("List");
}
And the processor:
public class FooSaveModelProcessor : IMessageHandler<FooSaveModel> {
public void Process(FooSaveModel message) {
// Message handling logic here
}
}
This is really just about moving the "processing" of the form out of the controller action and into individual, specialized handlers.
But, I'd only really go this route if controller actions get hairy. Otherwise, just take the form and do the appropriate updates against the domain models as necessary.
There are some similarities here with what I've been doing. My hierarchy of view models is only somewhat flattened from its domain object equivalents, but I do have to deal with calling explicit service methods on save to do things like adding to child collections, changing important values etc, rather than simply reverse mapping. I also have to compare before and after snapshots.
My save is Ajax posted as JSON to an MVC action and enters that action magically bound back to a view model structure by MVC. I then use AutoMapper to transform the top level view model and its descendants back into its equivalent domain structure. I have defined a number of custom AutoMapper ITypeConverters for those cases where a new child item has been added on the client (I'm using Knockout.js) and I need to call an explicit service method. Something like:
foreach (ChildViewModel childVM in viewModel.Children)
{
ChildDomainObject childDO = domainObject.Children.Where(cdo => cdo.ID.Equals(childVM.ID))).SingleOrDefault();
if (childDO != null)
{
Mapper.Map<ChildViewModel, ChildDomainObject>(childVM, childDO);
}
else
{
MyService.CreateChildDO(someData, domainObject); // Supplying parent
}
}
I do a similar thing for deletes and this process cascades quite nicely down through the whole structure. I guess a flattened structure could be either easier to work with or harder - I have an AbstractDomainViewModel with an ID with which I do the above matching, which helps.
I need to do comparisons before and after updating because my service layer calls trigger validation which can affect other parts of the object graph, and this dictates what JSON I need to return as the Ajax response. I only care about changes which are relevant to the UI, so I transform the saved domain object back to a new view model and then have a helper method to compare the 2 view models, using a combination of manual upfront checks and reflection.
I'm curious of all of the various ways people are building their ViewModels and why they choose that method.
I can think of several ways here:
-1. Injected repository - the controller loads the model and maps to the ViewModel. Here the ViewModel constructor could take various collections to interally set for ex. in a select list such as:
public CustomerController(ISomeRepository repository)
{
_repository = repository;
}
public ActionResult Create()
{
CustomerCreateViewModel model = new CustomerCreateViewModel(_repository.GetShipTypes,
_repository.GetStates);
..
..
}
-2. ViewModelBuilder - Either injected or instantiated in the controller with an instance of the injected repository. Called via something like
>var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
or,
var orderViewModel = orderViewModelBuilder.WithStates().Build(orderId);
-3. Directly in controller (no code required - its messy)
-4. Some other service (injected or not) that returns domain model which the controller then maps or a ViewModel (anyone doing this to return a view model that isn't specifically named/noted as a ViewModel builder class?)
public JobCreateViewModel BuildJobCreateViewModel(int parentId)
{
JobCreateViewModel model = new JobCreateViewModel();
model.JobStatus = _unitOfWork.JobRepository.GetJobStatuses();
model.States=_unitOfWork.StateRepository.GetAll();
return model;
}
Now on the return trip - regarding validating your view models - are you inheriting from a base ViewModel class for standard validations, or copying your validations (ex. data annotation attributes) between all of your ViewModels, or simply relying on server side validation so it can all be validated againt your domain object?
Any others? Anything better? Why?
EDIT
Based on a link below, I did find a nice article from Jimmy Bogard on the architecture of ViewModels. While it doesn't address the question above directly, it's a great reference for anyone coming here for ViewModel information.
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
I inject a service into the controller, not a repository, and then use AutoMapper to convert it into a view model. The benefit of the service layer in this case is that it could aggregate multiple simple operations from one or more repositories into a single operation exposing a domain model. Example:
private readonly ICustomerService _service;
public CustomerController(ICustomerService service)
{
_service = service;
}
[AutoMap(typeof(Customer), typeof(CustomerViewModel))]
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
return View(customer);
}
in this example AutoMap is a custom action filter that I can write which executes after the controller action, inspects the returned object and uses defined AutoMapper mappings to map it to the specified destination type. So the view gets the corresponding CustomerViewModel as model type. Would have been equivalent to:
public ActionResult Create(int id)
{
Customer customer = _service.GetCustomer(id);
CustomerViewModel vm = Mapper.Map<Customer, CustomerViewModel>(customer);
return View(vm);
}
it's just that it is too much plumbing and repetitive code that could be centralized.
I would also recommend you watching the putting your controllers on a diet video from Jimmy Bogard.
I just finished a project where we did a variation on #4. We had a service class injected into the controller. The service class held dependencies on the repository and a model builder class (we called it model factory).
The controller called into the service class, which handled business validation logic, and then fetched view models from the appropriate factory. The models themselves relied on data annotations for input validation.
It worked really well for our team. There was enough separation of concerns to allow the devs to do their work without affecting one another, but it was manageable enough to understand what was going on.
It's the first time we tried it and we'll be sticking with it. I'm interested to see how others respond.
Our method is to inject the repository in to the controller and map it to the ViewModel using Automapper http://automapper.org/. Our ViewModels contain data annotation attributes to allow the validation to occur on the client.
We call methods on the repository which return Domain objects (Entity Framework). The domain objects are mapped to the ViewModel. We tend to use the same ViewModel for edits and adds so the data annotations are needed once. In its simplest form it looks like the following code:
public ActionResult List(int custId, int projId)
{
var users = _userRepository.GetByCustomerId(custId);
var userList = Mapper.Map<IEnumerable<CMUser>, IEnumerable<UserListViewModel>>(users);
return View(userList);
}
I use a service layer that hides the domain model from the controller returning ViewModels from the service methods. This allows me to make changes to the domain model without impacting the client.
I have an MVC app divided into the usual layers: MVC presentation layer, Business Logic, and Data Access Layer.
In the MVC app I have a search form. It's a complex one - lots of checkboxes, radios, dropdowns and text fields. When the user submits the form I create an "EditModel" (ActionModel?) object in the Controller that contains a set of properties encapsulating the form.
The DAL needs to use the properties in this object to construct a query that returns the right results based on the user's selection.
What is the best way of passing this through to the DAL (which obviously has no reference to the MVC project). Is it to create a DTO which is exactly the same as the EditModel (ActionModel?) , just for the purposes of passing it from MVC -> BLL -> DAL? Are there any better ways?
If the object would truly be "exactly the same," why wouldn't you just use it in the BLL and DAL? It would make sense to have an assembly referenced by both the model and the BLL (and DAL).
Make a core / domain / bll representation out of your view model. I use mappers for this. In this example the controller would use IGuestDetailsMapper
public interface IViewToDomainMapper<TModel, TViewModel>
{
/// <summary>
/// Map presentation model to domain model. If message has a key it will first be loaded (edit mode).
/// </summary>
/// <param name="message">presentation model</param>
/// <returns>domain model</returns>
TModel MapViewToDomain(TViewModel message);
}
public interface IGuestDetailsMapper : IDomainToViewMapper<LoginContact, GuestDetailsForm>
{
}
If you use a form object, it often isn't EXACTLY the same as a core object because you might find you are adding validation / ui display label attributes or other bits and pieces that don't need to be in your domain model.
Another way to avoid creating a new object (if you really need to) but still have separation from the view model is create an interface mirroring the view model's properties you are interested in for your search, and apply it to your view model.
Then make the parameter type in your search method of the Interface type, and you can use the view model directly then.
I am pretty new to MVC and I am looking for a way to design my models.
I have the MVC web site project and another class library that takes care of data access and constructing the business objects.
If I have in that assembly a class named Project that is a business object and I need to display all projects in a view ... should I make another model class Project? In this case the classes will be identical.
Do I gain something from doing a new model class?
I don't like having in views references to objects from another dll ... but i don't like duplicating the code neither.
Did you encounter the same problem?
I usually use a combination of existing and custom classes for models, depending on how closely the views map to the actual classes in the datastore. For pure crud pages, using the data class as the model is perfect. In real world use though you usually end up needing a few other bits of data. I find the easiest way to combine them is something like
// the class from the data store
public class MyDataObject {
public string Property1 {get;set;}
public string Property2 {get;set;}
}
// model class in the MVC Models folder
public class MyDataObjectModel {
public MyDataObject MyDataObject {get;set;}
// list of values to populate a dropdown for Property2
public List<string> Property2Values {get;set;}
// related value fetched from a different data store
public string Property3 {get;set;}
}
I also have quite a few model classes that are just a set of form fields - basically corresponding to action parameters from a particular form rather than anything that actually ends up in the database.
If it is exactly the same project then obviously don't need to duplicate the Project class, just use it as is in the view. But in real life often views have specific requirements and it it a good practice to define view model classes in your MVC application. The controller will then map between the model class and the view model to be passed to the view.
You will likely find differing opinions on this. I will give you mine:
I tend to, by default, reuse the object. If the needs of the view change and it no longer needs most/all of the data in the business object, then I'll create a separate view. I would never change the business object to suit the view itself.
If you need most/all of the information in the business object, and need additional data, then I would create a view that holds a reference to the business object and also has properties for the additional data points you need.
One benefit of reusing the business object is that, depending on the data access technology you are using, you can get reuse out of validation. For isntance, ASP.NET MVC 3 coupled with Entity Framework is nice as they both use the attributes in the System.ComponentModel namespace for validation.
That depends on what you mean by model. In the architecture I typically use, I have my Domain model, which is a collection of classes in a separate class library. I use DataAnnotations and built in validation to automatically validate my model when saving.
Then there is the View model, which I place in my MVC project. View models only have the information relevant to the view. I use data annotations here as well since MVC will automatically use them for my validation.
The reason for splitting the model this way is that you don't always use every piece of your domain model in a view. That means you either have to rebuild the data on the backend or you have to stash it in hidden fields. Neither is something I like,.
I'm begginer in asp.net mvc and i have some doubts.
P.S: I'm using DDD to learn
I have an ACtion in a Controller and it'll save an entity (from my model) by a repository (for a database).
My doubts is, How can I get the informations from the View and save it by a repository in my Controller ?
Is it correct to get an entity of my Model in Save method of controller, like this:
public ActionResult Save(Product product)
{
// validate object
// save data in repository
return View("Success");
}
Or Need I get an DTO (with a structure similar to my entity) and create an object passing property by property to an entity ?
I didnt' like of FormCollection and I'd like to know, What is recommended architecturally ?
Thanks a lot guys
Cheers
I you want to follow DDD practices as described by the Blue Book you should bind your views to DTO's which can be forwarded to a thin 'Application' layer where Domain objects are created or retrieved from database. This application layer can be a simple facade with methods or can leverage command pattern.
For a live demo, you can see my project -- DDDSample.NET
This kind of problem can be fixed by adding so called view model.
Basically - a view model is DTO that provides data for particular view. In similar fashion - view models are used to get data back from view via model binding. Then - controller just forwards necessary data to domain model.
Typically, in ASP.NET MVC your controller actions will receive strongly typed objects returned by the DefaultModelBinder when editing entity types. Using this pattern you can pass a "Product" to your GET view either by itself or as part of a DTO and then your "Save" method would receive a "Product" object in its parameter list.
So long as you are using either editor templates or fields with matching names (i.e. Html.TextBox("Name") corresponds to Product.Name) then the DefaultModelBinder should be able to correctly fill the typed entity object passed to the action method. You shouldn't have to mess with the FormCollection except in certain edge cases.
[HttpGet]
public ActionResult Create() {
return View("Create", new Product());
}
[HttpPost]
public ActionResult Create(Product product) { //or Save(Product)
...
}
As long as your form has fields which match the fields in Product, they should automatically be populated for you based on the values. How you save the entity depends on the data model, whether you're creating a new record or editing an existing one, etc.