For the sake of simplicity, lets say I have a CustomerViewModel and I want to display their basic information (Name, Email, Phone, etc.) as well as a list of recent orders.
Should I have a collection property, say Orders of type OrderListViewModel, or should I use the POCO objects returned from the Repository?
I guess what I am really asking is should I have a View Model for every entity and then have collections of those attached to "Parent" View Models?
Yes, You should have ViewModels but you don't have to. If you are following DDD then you would never have a Entity reach the View. I have started small apps where I just used my domain objects as the Model for my views and later as the app grew regretted the design decision.
Here is a good post on the View Model pattern and how to use Automapper to help with the additional left to right: http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx
http://www.bengtbe.com/blog/post/2009/04/14/Using-AutoMapper-to-map-view-models-in-ASPNET-MVC.aspx
Your ViewModel should look something like this:
public class CustomerModel {
public string Name {get; set;}
public string Email {get; set;}
public string Phone {get; set;}
public OrderModel[] Orders {get; set;}
public class OrderModel {
public int OrderNumber {get; set;}
public double OrderTotal {get; set;}
}
}
Configure Automapper and will will keep all your concerns separated (SoC)
Basically, you should have a unique View Model for every unique view. The View Model should contain all data the view is going to present.
So, if you're presenting customer information along with orders, the View Model could have a customer instance and a order list:
class ViewModel
{
Customer Customer { get; set; }
IEnumerable<Order> Orders { get; set; }
}
I would recommend using a View Model even when a simple business object would do just fine. This makes it so much more easy to maintain and as we all know, requirements change.
AutoMapper is a wonderful tool that makes dealing with View Models a breeze.
Don't just create a view model for no reason. The view model should provide specific value of decoupling the model from the view as well as add additional items (dropdown lists, etc) that the specific view needs that you don't want to put in your model. A view model should map 1 to 1 to a specific view.
If you don't have that need right now for the above then don't create it.
i don't think there is anything wrong with starting with just the POCOs and creating viewmodels when you need them. I dont see a big issue with refactoring and creating a view model at the point that you need the decoupling in between your view and your model. For trivial cases i would avoid over engineering up front but know that your goal is to ultimately have view models as a solution to avoid coupling or add extra things the view needs.
Ideally you should have View Model for for every entity that the view deals with. Sometimes when the entity is too trivial, you could skip having a view Model I guess.
Related
I usually see people telling that you should not pass entities to your View. They say you should use a DTO/VO/ViewModel/AnyOtherThingYouWant instead, as using an entity would increase the coupling.
Ignoring the moments where I do need some extra logic (or I don't need all the properties), I fail to see any benefits in doing this. For example, consider the following class:
public class Contact {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
I see lots of code that creates another class, like this:
public class ContactDTO {
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
use it in the View and then do this:
someMapper.Map(contactDto).To<Contact>();
I can't see how better this is than simply using the Contact class, as your View would be coupled to a class that is coupled to the entity's class. So, every change in one should be replicated into the other. From my point of view, the 'middle' object is there just to add complexity, but not real value.
I know that there's no 'one size fits all' solution (as sometimes, using the middle object would make sense), but do we really need adding code like this? What are the real benefits?
Think of it this way: a view is a projection of your domain. It's a specific representation of your business model. So you need to use a view model which will represent this projection. It could be a subset of the domain model but it could also be an aggregation of multiple domain models if the view requires it. The example you provided is just a specific case where there is a 1:1 mapping between the domain model and the view model because of the requirements of this specific view. But that's only one specific view. I suppose that your application has many views and different representations of your domain entities.
There are many view specific things that make your domain models unsuitable and thus the need of view models. For example validation. A given domain model property could be required in some view and not required on another view (think of Id property in Create/Update views). If you don't use a view model but have your Create controller action directly take the domain model you will have a problem if your domain model Id property is decorated with the Required attribute.
There are many other examples. If I had one advice to give you when developing an ASP.NET MVC application it would be this: always define specific view models for your views and never pass/take domain models to/from views and this stands true even in cases where you have a 1:1 mapping between your domain model and the view model.
The cited approach is a kind of purism. If you do not need to transform (reduce, merge, whatever) your domain objects and they are directly usable in your view as they are, use them - you can introduce DTO via refactoring later, when necessary.
So you have to take into consideration what Darin Dimitrov said but keep in mind that DTOs and similar are here to make your work easier. I recall one project I worked on - more than 90% of DTOs were ono-to-one copies of the domain objects - this is totally useless and only adds to the maintenance cost.
I have a Service class with a method called GetProducts(). That encapsulates business logic and calls the repository to get a list of products.
My MVC view wants to show that list of products as an MVC SelectList. Where is the correct place for that logic to go. I seem to have 3 options:
Model
The Model should expose a property called ProductSelectList. When the getter of this property is called by the View, the Model should call Service.GetProducts() and convert the result to a SelectList before passing it on.
Plausible argument: The Model should make calls to business logic and the repository. The View should merely render predetermined data. The Controller should not be involved, save for passing contextual data to the Model.
View
The View should contain code that calls Service.GetProducts() directly and converts the result to a SelectList inline.
Plausible argument: The View should call for this data directly as it is specifically for use on the View. There is no need to involve the Model or Controller, as we are calling an abstracted Service method anyway, so anything else just adds extra overhead.
Controller
The Controller should make the call to Service.GetProducts(), convert the results to a SelectList and pass it through to the Model, which should contain a simple ProductSelectList property. The View will access this property for rendering.
Plausible argument: The Controller knows which parameters to provide to the Service method, so it should make the call. The Model should be a simple placeholder for data, filled by the Controller. The View's job is to simply render the data from the Model.
I have a feeling that the correct answer is Model, but the other two make some reasonable points. Perhaps I've muddied the waters by already having a Service class that's separate to the Model?
Would anybody care to share their opinion? Is this just a matter of taste?
I personally subscribe to the logic of Number 3, allowing the controller to populate the Model (or View Model as is sometimes differentiated).
I have my views dumb and only displaying data.
I have my View Models store the information that the View will need, occasionally exposing 'get only' properties that format other properties into a nicer format. If my model needs access to my services, then I feel I'm doing something wrong.
The controllers arrange and gather all the information together (but do no actual work, that is left for the services.
In your example, I would have my controller action similar to:
public ActionResult Index()
{
IndexViewModel viewModel = new IndexViewModel();
viewModel.ProductSelectList = new SelectList(Service.GetProducts(), "Value", "Name");
return View(viewModel);
}
and my view model similar to:
public class IndexViewModel()
{
public SelectList ProductSelectList { get; set; }
public int ProductID { get; set; }
}
With the appropriate part of the view looking like:
#Html.DropDownListFor(x => x.ProductID, Model.ProductSelectList);
This way I'm content that I know where to look if there is an issue with anything and everything has a very specific place.
However, there is no correct way as seems always to be the case with these things. Stephen Walther has a good blog series on MVC tips. In one he talks about the View Model emphasis and although not a SelectList he populates, the SelectList is still data in much the same way his list of products is.
In a classic MVC architecture your Model shouldn't be much more than a container for your view data hence the reason it's often called a ViewModel. A ViewModel is different from the Entity Model(s) that your service layer manages.
Your controller is then responsible for populating your ViewModel from the entity model(s) returned by your service layer.
Due to convenience some developers will use their service layer entities directly in their ViewModels but long term that can lead to headaches. One way around that is to use a tool such as AutoMapper to automate the shuffling of data to and from your ViewModel and entity models.
Here's what a controller might look like. Notice that data such as the SSN does not get exposed to the view since there is a mapping from your Entity Models to your View Model.
public class Customer : IEntity
{
public string CustomerID { get; set; }
public string SSN { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public Address Address { get; set; }
}
public class CustomerEditViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string PhoneNumber { get; set; }
}
public class CustomerController
{
[AcceptVerbs (HttpVerbs.Get)]
public ActionResult Edit ()
{
Customer customer = _customerService.GetCustomer (User.Identity.Name);
var model = new CustomerEditViewModel ()
{
FirstName = customer.FirstName,
LastName = customer.LastName,
Address1 = customer.Address.Address1,
Address2 = customer.Address.Address2,
Country = customer.Address.Country,
City = customer.Address.City,
State = customer.Address.State,
Zip = customer.Address.Zip,
PhoneNumber = customer.Address.PhoneNumber,
};
return View (model);
}
}
You're right that there are a number of ways to handle this, and that's even before considering variations like MVP, MVVM, et cetera. Since you're asking about ASP.Net MVC in particular, I will defer to Microsoft:
An MVC model contains all of your application logic that is not
contained in a view or a controller. The model should contain all of
your application business logic, validation logic, and database access
logic. For example, if you are using the Microsoft Entity Framework to
access your database, then you would create your Entity Framework
classes (your .edmx file) in the Models folder.
A view should contain only logic related to generating the user
interface. A controller should only contain the bare minimum of logic
required to return the right view or redirect the user to another
action (flow control). Everything else should be contained in the
model.
In general, you should strive for fat models and skinny controllers.
Your controller methods should contain only a few lines of code. If a
controller action gets too fat, then you should consider moving the
logic out to a new class in the Models folder.
Source
I would say your call belongs in the Model.
One thing to keep in mind is that the SelectList class is specific to MVC only. So in my opinion it shouldn't be included in any business logic, and model classes fall into that category. Therefore your select list should be a part of a view model class instead.
This is the way it works in my projects:
Controller method is called
Controller uses repository (business logic, in other words) to get model data
Controller converts the model data if necessary and creates a view model object
Controller passes the view model to the view
The view displays the data in the view model with limited logic to show or hide things, etc
I'd go with option 3. In general, I'll construct my MVC apps such that the controller makes a call to the service to return a model (or collection of models) which are then passed to the view.
I generally keep my models very thin. They are a flattened representation of the data with validation attributes and that's it. I use a service (or model builder) layer to construct the models and do business logic on them. Some folks embed that into the model, but I find that makes for a messy project.
You definitely don't want the view making any calls to your services.
Update...
I'm assuming that this SelectList is your model. If instead it's a part of your model, then you're right, you should put it in your model. I generally don't like to make it a method call, though. I'd have a property on my model:
public SelectList Products { get; set; }
And have my service or model builder class actually populate it. I don't usually have any data-oriented methods on my models.
I'm going with option 1.
Models are the place to make calls to business logic, et cetera.
View - Should display only what the ViewModel already has been populated with.
Controller - the job of the Controller is to direct the traffic coming in (from Web requests) to the Logic that is responsible for handling the request. Hence the term 'controller'.
There are always exceptions to these, but the best place (structurally) is the Model.
I had this problem when I started into MVC and came up with this solution.
The controller talks to a Service Layer. The service layer contains my Domain models and does all the processing for request from the Controllers. The service layer also returns ViewModels to satisfy requests from the controller.
The service layer calls a repository and gets the entities it will need to build the ViweModels. I often use Automapper to populate the ViewModel or collections within the view model.
So, my view models contain all that is needed by the View, and the Controller is doing nothing but handling request and forwarding them to the appropriate service handler.
I don't see a problem with having view specific items like SelectLists in the view Model either.
None of the above.
In my web layer I basically just have html and javascript views. The model shouldn't leak into the view and neither should the services.
I also have an Infrastructure layer which binds the services and model to the views. In this layer there are ViewModels, which are classes that represent what will be displayed on the screen, Mappers, which do the work getting data from services/model and mapping it to the view model, and Tasks, which perform tasks such as Saving, Updating and Deleting data.
It is possible to put a lot of this infrastructure in the Controllers, similar to the example Todd Smith has given above, but I find for anything other than trivial views the Controller becomes littered with code to load data and populate view models. I prefer a dedicated single responsibility mapper class for each view model. Then my controller will look something like
public class CustomerController
{
[AcceptVerbs (HttpVerbs.Get)]
public ActionResult Edit (int id)
{
return View (CustomerEditMapper.Map(id));
}
[AcceptVerbs (HttpVerbs.Post)]
public ActionResult Save(CustomerEditViewModel model)
{
var errors = CustomerEditUpdatorCommand.Execute(model);
ModelState.AddErrors(errors);
return View ();
}
}
I'm torn between option 1 and option 3. I've ruled option 2 out completely as to me that's polluting the view with procedure calls not just presentation layer work.
Personally I would do it in the model and the getter would call the Service layer but I also subscribe to the belief that the model should only contain the information the view needs to render the page, by not fully containing the data in the model at the time you pass it to the view you are breaking this.
Another option here though would be to avoid tightly coupling the view and model by putting a Dictionary of the Products into the view through a Service Call then using the view to transform the Dictionary to a SelectList but this also gives you the ability to just output the information as well.
I think this boils down to a preference as to where you are happy having your logic.
I'm trying to learn ASPNET MVC. I've built a DbModel starting from DB structure so, under Models, I have the .edmx file that can be used to access data.
I've read that it could be good to have ViewModels classes to act between the View and the Model (useful also for single fields formatting) but I don't' understand if this is right and in which way it's better to build them. If they reproduce classes in my model I believe it is a little bit redundant, isn't it? If this is the right way, is there a way to generate automatically ViewModel classes?
A ViewModel in MVC is a model of your view. It is a property bag containing, usually of primitive types. It may seem redundant, but you are protecting yourself from future problems by decoupling your code.
As an example, given a Person object in your domain model:
public class Person
{
public string FirstName {get; set;} // John
public string LastName {get; set;} // Doe
public DateTime Birthdate {get; set;} // 01/01/1965
}
In your view, you may want to represent this in a view as a full name, age and birthday. Your ViewModel would be similar to:
public class PersonViewModel
{
public string FullName {get; set;} // John Doe
public int Age {get; set;} // 46
public int Birthday {get; set;} // January 1
}
Somewhere in your pipeline, you need to convert from domain model to the viewmodel. I have used either projection queries from the persistence layer or object-to-object mapping frameworks, such as AutoMapper.
By structuring your data this way, you can keep logic and formatting rules out of your view markup. By using a framework, such as AutoMapper, you can also standardize string formatting of dates and times, and do convention-based mappings.
Also, I generally advise having one ViewModel per View. If you need to share View/ViewModel structures or apply conditional view information, those should be separated into partial views.
If you are just starting out I would avoid trying to incorporate every best practice you can find into your early applications. It becomes very easy to try and do everything everyone says is the best practice and you lose track of just learning the fundamentals.
View Models are obviously a great way of seperating the presentation layer and the domain layer, but they serve other purposes. If you are just starting out and your applications are not terribly complicated, I would recommend keeping it simple and use your domain classes as your view model where your views are simple. This will allow you to focus more on the application.
Also, by doing this you will come across views where the simple domain model will not cut it and you will find yourself needing a ViewModel. Which will allow you to incorporate the more specific information you need for your view page (such as multiple domain objects).
By practicing without using View Models for everything, you can gain an appreciation for their benefits and decide what works best for you and your code.
A "view model" (model for a view rather than domain model) helps you separate the domain model from what is bound to the page. Is it always necessary? No, but it is useful if you have some common data shapes used on multiple views where the view will also have some additional data. Another good use is removing certain data from certain types of views (your customer should not know your margin, but your management should?). IT is not mandatory.
Short question - how do you define your view models?
Here are some of the options:
Pass the actual model into the view.
Create a view model with a reference to the model (like Model.Product)
Create a view model with the properties needed from the model, and set those from the model.
Probably a lot more.
All with their own advantages and disadvantages.
What is your experience - good and bad? And do you use the same model for GET/POST?
Thanks for your input!
Basically - it's all about separating responsibilities.
More you separate them - more verbose, complex but easier to understand it gets.
Model:
public class foo{
string Name{get;set}
Bar Bar {get;set;}
string SomethingThatIsUneccessaryInViews {get;set;}
}
public class bar{
string Name {get;set;}
}
public class fizz{
string Name{get;set;}
}
Presenter (i admit - still haven't got idea of MVP completely):
public someSpecificViewPresenter{
fizz fizz{get;set;}
foo foo{get;set;}
necessaryThingsForWhatever[] necessaryThingsForWhatever{get;set;}
public void someLogicIfNeeded(){...}
}
magic object2object mapping & flattening, viewmodel modelmetadata configuration goes here...
ViewModel (NB=>POCOS with container props only. No logic should go here.):
public class fooViewModel{
string Name {get;set;}
string BarName {get;set;}
}
public class fizzViewModel{
string Name {get;set;}
}
public class someSpecificView{
fooViewModel foo {get;set;}
fizzViewModel fizz {get;set;}
whateverViewModel whatever {get;set;}
}
and here goes "das happy ending"...
<use viewdata="someSpecificView m" />
<p>
Our foo:<br/>
${Html.DisplayFor(x=>x.foo)}
</p>
<p>
Our fizz:<br/>
${Html.DisplayFor(x=>x.fizz)}
</p>
${Html.UberPaging(m.whatever.Paging)}
And yes, i use same model for GET/POST. See this for more why/ifs.
But lately - I'm looking for other solutions. CQRS buzz catch my eye.
In my projects, it's a mix really.
If I want to display a form with details of Customer X, I just pass a DAL Customer object to my view. It's really no use to create a seperate ViewModel for it, map all its properties, and then display them. It's a waste of time imho.
Sometimes though, models are a bit more complex. They're the result of multiple queries, have some added data to them, so in these cases, I create a custom ViewModel, and add the necessary data from my model to it. In your case, it would be option 2, or sometimes 3. I prefer that over passing my model and having to add an additional 10 items in my ViewData.
I grabbed the T4 templates from SubSonic 3. These were modified and I added some new ones. I can run one of them and it generates 3 separate view models for each table. Then I can modify as needed.
Why three?
FormModel - contains on the data necessary for displaying in a form for editing or creation. Foreign keys get converted to SelectLists. DateTime fields get split into date and time components.
PostModel - this is the object returned from the Form Post. DropDownLists are posted as Int or equivalent type. Only the necessary members are in the model.
DisplayModel - used for non-editing display of the data.
I always generated these in a subfolder named Generated. As I hand tweek them I move them to the Models folder. It doesn't completely automate the process, but it generates a lot of code I would otherwise generate by hand.
In asp.net mvc, I have been thinking it would be more advantageous to specify parametrized constructors on the view classes in contrast to using ViewData to pass data to the view. In this way the view class could be instantiated in the action and returned from there as an implementation of IView for eventual rendering to the client by the framework.
// An example of an action that returned one of two
// views while passing a data objects from the current
// scope.
IView MyAction(discriminator){
if(discriminator){
return new MyView(SomeVal, SomeVal2)
}else{
return new AnotherView(SomeVal1)
}
}
// An Example Definition for IView
public interface IView{
Render(stream OutputStream);
}
// An Example View Code Behind/Partial Class
public partial class AnotherView{
public AnotherView(string GimmeData){
this.GimmeData = GimmeData
}
// This value could be accessed in the markup like:
// <%=this.GimmeData%>
public string GimmeData {get; set;}
}
I pose this question because I have personally found strongly typed views pointless as there is not 1 or 0 but n number of objects I would like to pass to the view from the action. I also find the ViewData collection a little too "untyped" to mesh really well with the .net strongly typed world.
A parametrize constructor or even public properties on the view would allow the implementer of the view to specify a contract of what data is needed to render the view or can be rendered in the view. This approach would effectively encapsulate the view.
Why would this be a bad design? What advantages are provided with the "viewdata collection"/"strongly typed view" "way" of passing data from the action to the view. Does anyone think this would be a good idea?
update
I have had a change of heart. What I realized is that the view is really just about rendering. A very good design approach is to introduce Presentation Models that represent the user interfaces available in your application.
If something can be shown or not there should be a Boolean in your presentation model. If something can display text there should be a string for that in your presentation model. The presentation model is not anemic because you use it to encapsulate the logic of your UI. For example, if a field is empty then perhaps some other field is grayed out. This is presentation logic and it describes the way that your particular UI works.
Once a presentation model has been introduced the generic page classes work fine, you simply pass the view the correct presentation model. Presentation models allow you to clean up the code in your view as well as provide portability. If one decided to implement in winforms they would seriously only need to bind their UI to the presentation model.
Anyway, I just wanted to follow-up because I no longer agree with my original suggestion. I have accepted Travis's answer because this is essentially what he proposed.
The convention is usually to provide a View Model that encapsulates the data you need in your view. You can then pass this strongly typed object down into your view. So, for example, you might have a BlogDisplay object that looks like this:
public object BlogDisplayPage {
public string PageTitle {get; set;}
public BlogEntry Content {get; set;}
public IList<Comment> Comments {get; set;}
public IList<BlogEntry> RelatedEntries {get; set;}
public IList<BlogEntry> PreviousEntries {get; set;}
}
Excuse the contrivedness of the example, but I think you understand what I'm trying to get at. This way, you can have all of the data associated with the View in one object that can be easily tested and maintained. This also has the advantage of having strongly typed Views using generics.
I prefer this over your suggestion of parameterized constructors because its intent is clear, and the creation and aggregation of that data is going to be in one spot that will probably be easier to maintain.