I'm using asp.net mvc 2 and I'm not sure howto structure the models and viewmodels. In the nerddinner there is only 1 of each.
Shall I have only 1 viewmodel of each entity (?) and then have 1 model for each form-modifing viewpage? So that viewmodel contains like all it ever would need, like: PagedFoo FooClass ..., FooClass, Foowithbunnies, FooClassStats... ?
/M
The way I view this is that (Domain) Model objects represent your business entities. Anything the business requirements dictate go there.
View Models are there to make the view as simple as it can be. So all the display logic, data massaging etc., goes there.
And yes, there will be times where one will seep into the other (Hey, you got your View Model/Peanut Butter in my Domain Model/Chocolate!), and it's OK.
But your goal should be to keep them as separate and clean as possible. This seems to lead to the most re-usable and easy to maintain code.
I generally have a ViewModel which will represent a View. This is to keep the view as dumb as possible.
So, for now, it's a 1 to 1 relationship. View -> ViewModel,
but my ViewModel has a one to many relationship with my Model
extract
View |----| ViewModel
ViewModel |----|< Model
I inherited an app where one of the database tables has about 60 columns. This represents a persistent type that is constructed over the course of several pages within the app. To resolve this, I created about 8 different view models.
So... think of ViewModels in the same way as you would a SQL View table (if the metaphor helps). A ViewModel is a mechanism you use to help constrain the use of a Persistent Type to something that's useful for your view.
Also, I highly recommend using AutoMapper when working with transitions between ViewModels and Persistent Types, it makes dealing with ViewModels feel a lot more natural.
Related
I have read online that it is bad practice to use a "kitchen sink" model:
Rule #3 – The View dictates the design of the ViewModel. Only what is
required to render a View is passed in with the ViewModel.
If a Customer object has fifty properties, but one component only
shows their name, then we create a custom ViewModel type with only
those two properties.
Jimmy Bogard's subsequent explanation of how this is good, however, left me a little questioning. It'd be so easy to have my Model just contain a list of Customers, I could even use my POCO's.
So now I get to create custom little view model fragments for every page on the site? Every page that uses a Customer property would get one, but of course could not be shared since some of the information is extraneous, if one page used Age but not Name, for example. Two new mini view model classes right?
This is very time consuming, and seems like it'll lead to a million little custom view models - can someone elaborate as to the utility of this approach and why the easier approach is bad?
View model class can be used not only to transfer values, but it also defines data types (data annotations), validation rules and relations different then ones used in model. Some advantages that come to my mind right now:
There are different validation rules when you change user's password,
change his basic data or his subscription setting. It can be
complicated to define all these rules in one model class. It looks
much better and cleaner when different view models are used.
Using view model can also give you performance advantages. If you
want to display user list, you can define view model with id and name
only and use index to retrieve it from database. If you retrieved
whole objects and pass it to view, you transfer more data from
database than you need to.
You can define display, and editor templates for view models and reuse them on different pages using html helpers. It looks much worse, when you define templates for model POCOs.
If you would use your POCO objects as view models, you would essentially be showing your private objects and break the encapsulation. This in turn would make your model hard to change without altering the corresponding views.
Your data objects may contain details that are appropriate only to the data access layer. If you expose those things to the view, someone might alter those values that you did not expect to be altered and cause bugs.
Many of the same reasons as for having private members in OO languages apply to this reasoning. That being said, it's still very often broken because it's a lot of extra work to create all these "throw-away" models that only gets used once. There exists frameworks for creating these sorts of models, though the name eludes me, that can tie objects together and pick out the interesting properties only which takes away some of the drudgery from creating specific view models.
Your View Model tells the View how data should be shown. It expresses the model. I don't think its necessary to have two view models unless you have two ways to express your model. Just because you have two pages, doesn't mean you will be showing the data any different way, so I wouldn't waste time making two mini View Models when it can be in one reusable view model, Imagine if later you have a page that needs Name and Age, you would create another view model? It's absolutely silly. However, if you had two pages both showing 'Age' and it needed to be shown in a different way, then I would create another one.
I have a series of inherited objects that are all very similar with just a few fields varying between classes. At the base of this class hierarchy is an abstract class that contains many several fields that all subsequent objects should have. Something like this:
abstractBase
obj1 : abstractBase
obj2 : obj1
obj3 : obj2
The view that displays these objects is essentially the same for all of them, i just introduce new divs to display the data that is different. As I am fairly new to MVC this leaves me with just two primary options:
One approach would be to create strongly typed views for each concrete object. Each view would be very similar but with slight differences for the underlying objects. In my mind this violates the DRY principal as 90% or more of the content of each view would be repeated in the next one. But on the upside the views would be void of any significant logic.
The other approach would be to bind the view to the base abstract class and then introduce checks against the inherited classes to determine if i need to render out something. something like:
if (Model.baseObject is obj3){ render out the special fields }
On the upside, i will no violate the DRY principal, which i view as a good thing. But on the downside the views will then contain logic. As i understand it, this is more or less frowned upon.
Anyone out there been in a similar situation?
What approach did you take?
Is there another option I did not see/was not aware of?
Right now I am leaning *towards heavier views and less redundant code. it SEEMS better.
Thanks
I agree with the chosen answer to How much logic is allowed in ASP.NET MVC views?
Essentially views are meant to serve as a structure for the display of your model data. Therefore, the view is serving its purpose if the structure it creates for the display of a specific model can be adjusted based on the data contained in the model. Conditionally displaying elements in your view based on certain properties of the model it is meant to render is an acceptable practice.
If your view contained logic to modify the model data in any way, this would violate the separation of concerns that MVC is meant to establish.
I think you should follow the first approach having strongly typed views. You can have ViewModels which are specific those views and then bind to the view. Wherever you feel Reusability of a ViewModel present in another View, Make use of PartialViews.
Been working on a pet project on the side to learn asp.net mvc better. My question is about viewmodels in mvc. I understand the controller is supposed to handle the interaction between the view and the model. I feel like I keep having to create viewmodel classes to combine information from the models to pass to the view.
Is this bad practice? Should I be doing more of the logic elsewhere and cut down on the viewmodels?
At the moment I've almost got a viewmodel for just about every one of my main views. But I definitely don't want the view to access the model directly.
No, all your views should be strongly typed, so using for each view one viewmodel is best practice. Here is very nice article about viewmodels.
The more viewmodels you use the better. The viewmodels allow you to create a single object that can contain different types of data from your models. These are very useful when creating templates. Also, this is very useful when using JQuery and Ajax since its a nice way to pass data into your controller and then directly to the DOM. In my opinion, use as many viewmodel as you desire.
Another thing that you might consider is to try to have better design of your model. I personally try to build my model just like a sql database and follow the normalization forms. You should not have to create a new viewmodel for each view in addition to the models you already have. If you need to pass information to the view that is not part of the model you are using, use ViewData or ViewBag. These are passed as an object so you will have to cast them to the appropriate class.
Nothing bad in this. As much your viewmodel closer to view as better.
Model could not particullary match View, so you use ViewModel class for that.
Great answers here, and here is my view on why a lot of view models are not an issue.
Your ViewModels are a nice way of separating your pure Data Access Objects or even your Domain Objects from your presentation layer and provide a dumbed down version of those objects for your views to consume.
Your views are supposed to be dumb and for me personally, what I try to achieve is to massage my domain model into a ViewModel for my view to consume.
Using lot of viewmodels creates mess in your project. It is much better to just create a Tuple in the controller then pass it.
I am wondering if it is a good idea or bad, placing things like a List of countries in ViewModel, for binding to a drop down list? For example on a site's Registration page.
I was under the impression that a ViewModel is supposed to represent an instance of the filled out form, but I think I may be wrong as I have seen other people put things like lists in their ViewModel.
Would it not be better to put it in a static class somewhere and called directly from the View?
Like CommonData.ListCountries(); and then using Lambda to convert to SelectList item list in the view Directly?
As you've realized there are a variety of ways to accomplish your goal. While the MVC design pattern encourages certain application organizations how you organize your models, views and controllers is ultimately a matter of preference.
Scott Allen discusses his preference for dealing with ASP.NET MVC drop down lists in a blog post. Scott uses an extension method to convert an enumerable of a complex type into an IEnumerable<SelectListItem> on his model. He then describes that upon post back ASP.NET MVC will not be returning the IEnumerable<SelectListItem> he sent to the view, but only the value the user selected. He then suggests that utilizing two models can simplify things.
This is a reasonable description of what I refer to as ViewModels and FormModels. A ViewModel carries the display data to the view and a FormModel is used for carrying collected data back to a controller action. To explain further:
ViewModels contain data that help render views. By organizing my ViewModels this way I can place all necessary information to render a particular view into an associated model. This prevents me from having to use ViewData for anything that's not truly temporary.
FormModels are used to gather user input. FormModels (almost) never contain references to other complex types and are made up of primitives, DateTimes, and strings.
In either case I have a hard rule to never reuse a model for a different view. Having your models closely aligned with the views used to render them makes your views easier to write. You don't have to worry about things like static methods because your models should be carrying data to their associated views in a form that is easy for them to render. Tools like AutoMapper can help "flatten" domain objects into models for display purposes.
For additional reading checkout: ASP.NET MVC terminology is tripping me up - why 'ViewModel'?
Whatever data your View needs, put it in the ViewModel.
The way i see it, once your view is going through the rendering process, it should have all the info it needs from the Model it is bound to.
If you start to use helper methods, then the View is "going back to the controller" in a sense. Extension/helper methods are fine for formatting, etc, but they should not call through the model.
Don't forget, you also have ViewData (basically HttpContext.Current.Items, lives for single request), which is a lightweight storage mechanism that can be used to share data across partial views (for example).
How do most developers handle Typed Views in ASP.NET MVC when dealing with large applications? We are considering putting View-specific models in the Models folder, then putting all domain objects into a separate project. This way our Controllers can easily add the domain object to the typed view, without the domain object needing to be aware of the View layout itself.
For example, if we have an Employee object with:
Id
First Name
Last Name
Status
Then our Employee View might use a ViewEmployeeModel object with:
Employee object
List to populate Status drop-down
etc
Is this a sensible approach? Are there better ways to accomplish the same thing? It seems a little strange since I'd basically have two models (one for the view, one for the business objects), but isn't it better than using untyped views?
I do this almost as a rule, because:
It lets you design the app view-first instead of DB-first, which is nice when working with customer representatives.
Views typically have a much "flatter" object graph than, say, Entity Framework models. LINQ makes it easy to map these.
The views and the data model can evolve much more independently.
It's typically easier to model bind to a flat view model with, say, FK IDs than an entity model which expects fully materialized related objects.
You don't have to worry about accidentally exposing "secret" properties or whitelisting properties for updates.
Don't have the reputation to comment, but Craig is right. It's a variation of the Model-View-ViewModel pattern. There's a good article on it available at Los Techies.
The article also uses the AutoMapper code that mgroves pointed out so you should be able to kill two birds with one stone.
I think this is a pretty sensible approach. One thing that might help you out is AutoMapper.
Seems fine, you have the advantage that the model only contains information needed by the view and not lots of pesky business logic functions / values.