ViewModels and rendering - asp.net-mvc

In several sample projects, I've seen ViewModels being used to convert data objects into strings, for use in the View.
The ViewModel will typically have a constructor that receives one parameter - a data object. The constructor will then populate various properties of the ViewModel (mostly strings and ints).
This prevents any complex logic from occurring in the View.
At first glance, this seems like a good idea to me, as it more fully enforces separation of the View from complex logic.
For example, say my view was trying to render a property 'Size' of a data object, Size being a number between 1 and 3 representing 'Small/Medium/Large'.
Instead of having a if/switch statement in my view, I would just have a 'SizeString' or something similar in my ViewModel, and the if/switch statement would go in the ViewModel constructor.
Does anyone disagree with this approach?
Would it be better to use some other approach, such as helpers? And if so, why?

The purpose of the ViewModel is to represent (a part of) the complex Domain Model decomposed as primitives that can be rendered in some form other other.
This decomposition must take place somewhere. It may involve some simple kind of logic, such as my favorite example: converting a discrete value (OK, warning, error) into colors (Green, Yellow, Red). This is the essence of what a ViewModel does, so my default approach would be to encapsulate this logic into the ViewModel itself.
Consider the alternative: If not implemented in the ViewModel, then where? If you put the logic somewhere else, you end up with a ViewModel that's basically just a structure without logic. Letting a ViewModel encapsulate the transformation/decomposition of a Domain Object fits well with the Single Responsibility Principle.
Although this is my default approach, I'm always aware that the logic may need to be reused across multiple ViewModels. In such cases, this may be an indication that the original ViewModel is really a complex ViewModel made up of several sub-views. In such cases, you can extract the common logic into a sub-ViewModel that encapsulates only that little part.

It converts everything to string because everything in web is a string.
Basically - view model is supposed to be in 'ready to output' state. If web were made from numbers only - we would transform everything to ints/decimals.
Whole point of viewModel - to format data representable. In your case - size enum to small/medium/large. It's not that detaching logic from views makes this valuable - it's ability to adept your data for web in one way, one place.
Answering to comment =>
Yeah, that sits well. I'm doing the same. But thing to mention - I'm not against putting that into views too. Because views and view models are last in 'dependency chain'. I'm quite pragmatic and completely against only to situations when developer uses domain model as view model and requirements for view model gets in conflict with domain model (i.e. when developer adds new "domain objects" for representational purposes only).

Related

Scope of viewmodels in asp.net MVC 3

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.

DRY principals vs. light/thin views in MVC for similar/inherited objects

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.

In MVC3, should I have separate "edit" models vs. "display" models?

With MVC3, should I design my view models such that there is one that is bound to the view (DisplayModel), and one that is posted back to the controller (EditModel)?
To clarify, I am not asking about data models vs. view models -- I know it's not good to bind my views/controllers to data/domain models.
Nor am I asking about sharing one model across two separate views, one view that is used for displaying the data, and another view that is used for editing the data.
Rather, I am asking about one view that is used for editing data, and the model that is bound to the view vs. the model that is bound to the controller action.
In other words, if this is my view:
#model MyApp.Models.CustomerModel
Should my controller action look like:
public ActionResult Index(CustomerModel model)
Or:
public ActionResult Index(CustomerEditModel model)
At one point, we were doing the latter (separate). But lately, we've started doing the former (shared).
The reason for this change was because:
With MVC3 unobtrusive validation, if I'm using DataAnnotations on my model for validation, this is needed in both models if they are separated (on the display model to map client-side validation, and on the edit model for server-side validation).
As our application matured, we realized that our display and edit models were 95% identical, with the exception of the select lists that were in our view models. We've now moved these to a shared class and are passing these in via the view now.
But I've seen some other discussions that point to having shared models for view/controller to be a bad idea, and that it violates separation of concerns.
Can someone help me understand the tradeoffs for these two approaches?
I've seen perfectly good arguments for and against, it just depends what works best for your application. There's no one size fits all approach that can be applied!
If you haven't read it Jimmy Bogard has written a very good post about how his team does MVC here, which covers this topic.
I agree with rich.okelly's answer that there's no right approach.
There are a couple of concerns I have with using one model, though.
It's going to be very to always use one model without having unneeded properties when the view needs to display a selectable list of objects. The model will need to have the list of objects as well as a property to accept the POSTed value the user chooses. These unneeded properties add a small amount of code clutter and overhead.
(One way around this is to have the model contain only selected ID and have HTML helpers to build the lists.)
Another concern is more related to security.
A common scenario is displaying information in a form that should be considered read-only.
In the case of a ViewModel and an EditModel, the EditModel will only contain properties that are expected to be POSTed, whereas the ViewModel will contain all of the properties.
For example, if a form displays a user's salary, a user will be able to POST a 'salary' and have it bound to the ViewModel's Salary property automatically by MVC.
At this point, something has to be done to ensure it doesn't end up in the database. It could be if/else logic, a Bind attribute, Automapper logic or something else, but the point is that it's a step that could be overlooked.
When considering the lifespan of an application, I like the explicitness of the EditModel over time.
These concerns don't mean that two models are good and one model is bad, but they should be considered when choosing a design.
If the properties are the same for display and edit view models I see no reason to have separate classes.
I think you'll find that it's hit or miss no matter what way you go but if you can take the path of easiest maintainability then you should do that. In my experience, having a single model is much easier to maintain, obviously, but it seems that there is always some business decision that is made that forces me to split the models. If you're in that 95% then I think you are in really good shape. Your application, from a maintainability perspective related to your models, will be easy to maintain. When a change comes along, you have one place to make that change, for the most part. The issue I always seem to run into is scaling business changes across multiple models. Copy/paste issues, or simply forgetting about some property somewhere, always seems to hurt me because of the multi-model issue.
we realized that our display and edit models were 95% identical, with the
exception of the select lists that were in our view models. We've now
moved these to a shared class and are passing these in via the view now.
Are they 95% identical in data and operations or only in data? Remember that classes encapsulate data and behavior.
If they are 95% similar in properties but have totally different operations you might benefit from splitting them in two classes. Or you might not :)
As others pointed out there is no one-size-fit-all answer and in your case it seems that one class is OK...but if you start noticing that the behavior on each of them is unrelated don't be afraid to rethink you approach.
No - one view model for both directions. Mixing it up is not only harder to follow, but one could easily inject invalid values into the page that then get automatically bound. I could overwrite your customerid (or create one) for example.
Inherit from a base view model if you must or don't rely on data annotations at all and use the fluent api on your model save.
A great link (somewhat unrelated but the auto map is nice)
edit
(sorry someone else previously posted this below I just realized)
http://lostechies.com/jimmybogard/2009/06/30/how-we-do-mvc-view-models/
Also
ASP.net MVC - One ViewModel per View or per Action?
You (IMHO) should be generally binding to your method specific VieWModel rather than a shared view model. You could get caught in a trap of missing properties, etc. but it may also work just fine for you.
Use auto mapper to go between both. Jimmy also has a nice AutoMap attribute when returning to the View. Going back the other way I would not use a CustomerModel in general as there may be fields required in there that are not coming from my say, create view. For example a customer id may be a required field and for a "create" action it won't be present. But - if you find in the most of your cases this to actually work for you, then there is no reason at all not to use it.

best practice for what is in a ViewModel

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).

ASP.NET MVC terminology is tripping me up - why 'ViewModel'?

I'm an ASP.NET MVC newbie, but have used many Model-View-Controller frameworks previously.
I recently came across the convention of gathering up the pieces of data that your particular view needs (indeed, it's assigned to the ViewData) into a new class called (NameOfView)ViewModel.
Gathering up this data so that it's associated with the functions provided by the View/Controller interaction strikes me as a helper struct, or even closure mechanism (in the 'encapsulates a collection of variables' sense).
So why is it called 'ViewModel', given that it's neither a View or Model?
Does anyone else find the name confusing?
EDIT: What's wrong with just putting properties onto the View so that the Controller can populate them (as in other MVC frameworks)?
In my reading on this topic I've come across a variety of arguments as to why a developer would or would not want to use a ViewModel. Some even argue that a ViewModel should never expose anything more than strings. At this point I am not that extreme in my thinking. I will agree however, that it is not a good idea to expose Domain/Core Objects to the view. After some first hand experience it feels cleaner to remove this dependency.
While I don't agree with everything below Daniel Root makes a pretty good case for a ViewModel:
Most MVC examples show directly using
a model class, such as a LINQ-to-SQL
or Entity Framework class. The Visual
Studio wiring for MVC even steers you
into this concept with it's default
"Add View" code-generation, which lets
you quickly gen up views based on a
single model class. However, in
real-world-apps you often need more
than just a single table's data to
build out a page. Some examples get
around this by stuffing secondary data
into ViewData, but a better way to do
this is to create a "roll-up" class to
contain properties for everything
your view will need. This has the
added benefits of being more
strongly-typed, supporting
intellisense, being testable, and
defining exactly what a view needs.
Jeff Handley gives a nice description of the ViewModel pattern which he argues can be used in conjunction with MVC.
Edit
I've recently brought my thinking in line with Jimmy Bogard's regarding view models. After a fair amount of pain with each implementation I've tried having one view model per view creates a much cleaner development experience.
The model is a view-agnostic representation of the data. The view model is a view-specific representation of the data: it's the model as it might appear from a given viewpoint.
Consider a model that consists of raw data points; a histogram view might then have a view model consisting of a set of buckets and totals drawn from that data.
Logically, it's a subset or transformation of the model - it could be generated on-demand with a view-specific function and the model as its only input.
Regarding properties on the view vs. a property bag or custom object... I'm sure someone has strong feelings on this, but personally I don't see the big difference. You're producing a view-specific representation of the model and passing it somehow; the exact mechanism doesn't seem all that important.
Re: why can't the controller populate properties on the view?
Because the view doesn't exist at the time the controller action is executing. The idea behind returning an ActionResult from your action is that something later in the processing pipeline will evaluate the result and determine the best course of action (perhaps rendering a view, or maybe selecting a view to match the request (like special views made for mobile devices)).
I did a view posts on selecting the right kind of model object here: Putting the M in MVC Part I, Part II, Part III.
And yes, the term "ViewModel" term is en vogue right now, but it is in the spirit the original MVC adopters had in mind.
This isn't actually an answer but I highly recommend you watch the MVC2 Basics video by Scott Hanselman. It explains everything, and even though I have done ASP.NET MVC before it made a lot of things clear for me.
Its here: http://channel9.msdn.com/Blogs/matthijs/ASPNET-MVC-2-Basics-Introduction-by-Scott-Hanselman
It's called that because it's a "Model made for a View". I understand why the choice of term is a bit confusing.
It's a helpful approach if you don't want all your data passed to the view as a big hash array. It gives you a strongly-typed class dedicated to the UI, which pollutes neither the core Model or the View. It also allows you to encapsulate UI logic -- views should be kept dumb.

Resources