Have one Doubt In MVC Architecture we can able to pass data from Controller to Directly view without creating strongly typed view, than why there is need to use Models ..?
Is it decreases the Performance of the application if we are saving data in ViewData[""] and use it in Views to display Information . . ?
Storing data in a collection (ViewData) technically will be ever so slightly slower than passing in a strongly typed model (concrete class), but the difference is extremely small. There is also a tiny increase to the memory footprint (because you need memory for the collection and for the thing(s) in the collection) but again, that should be inconsequential.
Strongly typed models provide a clear contract between the controller and the view. I prefer them in all cases personally.
There can be simple views where the developer feels it unnecessary to create a strong type to represent the controller/view contract. For that need, ViewData exists.
I imagine that ViewData is also used by some to pass extra data not originally envisioned in the strongly typed model. I would encourage refactoring the strong type in such cases rather than passing extra data in ViewData.
There may be "legitimate" uses of ViewData that I'm missing, but I have not come across any thus far.
Related
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).
Assuming you wanted to develop your Controllers so that you use a ViewModel to contain data for the Views you render, should all data be contained within the ViewModel? What conditions would it be ok to bypass the ViewModel?
The reason I ask is I'm in a position where some of the code is using ViewData and some is using the ViewModel. I want to distribute a set of guidelines in the team on when it's right to use the ViewData, and when it's just taking shortcuts. I would like opinions from other developers who have dealt with this so that I know my guidelines aren't just me being biased.
Just to further Fabian's comment; you can explicitly ensure viewdata is never used by following the steps outlined in this article. There's really no excuse not to use models for everything.
If you have no choice but to use ViewData (say on an existing project); at the very least use string constants to resolve the names to avoid using 'magic strings'. Something along the lines of: ViewData[ViewDataKeys.MyKey] = myvalue; Infact, I use this for just about anything that needs to be "string-based" (Session Keys, Cache Keys, VaryByCustom output cache keys, etc).
One approach you may wish to consider as your views become more complex, is to reserve the use of Models for input fields, and use ViewData to support anything else the View needs to render.
There are at least a couple of arguments to support this:
You have a master-page that requires some data to be present (e.g. something like the StackOverflow user information in the header). Applying a site-wide ActionFilter makes it easy to populate this information in ViewData after every action. To put it in model would require that every other Model in the site then inherit from a base Model (this may not seem bad initially, but it can become complicated quickly).
When you are validating a posted form, if there are validation errors you are probably going to want to rebind the model (with the invalid fields) back to the view and display validation messages. This is fine, as data in input fields is posted back and will be bound to the model, but what about any other data your view requires to be re-populated? (e.g. drop-down list values, information messages, etc) These will not be posted back, and it can become messy re-populating these onto the model "around" the posted-back input values. It is often simpler to have a method which populates the ViewData with the..view data.
In my experience I have found this approach works well.
And, in MVC3, the dynamic ViewModels means no more string-indexing!
I personally never use ViewData, everything goes through the Model, except when im testing something and i quickly need to be able to see the value on the view. Strongtyping!
In terms of ASP.NET MVC 2, ViewModel pattern is the preferred approach. The approach takes full advantage of compile time static type checking. This in combination with compiling mvc views will make your development work-flow much faster and more productive since errors are detected during build/compile time as opposed to run time.
When is it appropriate to store data in HttpContext.Current.Items[...] vs storing data in ViewData[...]?
I'm trying to figure out the best practices for storing data in this collection and I'm not sure if it's safe to store user-specific data in HttpContext.Current.Items.
One use-case is passing down user credits from a base controller's OnActionExecuting(...) to be used in Controller calculations and for display in Views; I know I should be using ViewData for this, but I've had some inconsistent results with nested partial views.
Would it be correct to say that HttpContext.Current.Items[...] is to Controllers like ViewData[...] is to Views?
HttpContext.Current.Items only lasts for the duration of the request, but it is global to everything in that request.
Session obviously lasts for the entirety of the user's session, and persists between requests.
You should be able to figure out which one you need to use based on those criteria alone. Using HttpContext.Current.Items is not something I would recommend as it tends to be a kind of "global variable", and magic key strings tend to get involved, but sometimes you really do need to use it.
Additionally, although your comparison between .Items and ViewData is pretty apt, .Items differs from the way that ViewData behaves, because every View involved in the request (partial or otherwise) gets their own copy of ViewData.
The behaviour difference is clear when you do a RenderPartial and try to add something to ViewData - when you go back up to the parent view, the item is not there.
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).
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.