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.
Related
I am starting with MVC since a few weeks and now I have a best practice question:
I have basic data of my project, which are around 30 to 40 propertys, mostly strings.
I have a model with all my propertys for this data called "GeneralDataModel" and of course a Controller "GeneralDataController" and my View "GeneralDataView".
Now I want to have a setting page for this data.
I created a view (GeneralDataSettingView) a controller (GeneralDataSettingController) and a Model (GeneralDataSettingModel).
In fact, most of the data are the same, e.g. I have to load all data into the model when the view is loaded to display them in my TextboxFor.
Some methods are not the same, e.g. a method to save my data which only my setting page but not the display page have.
I know a few methods to have not the same model data and controller methods over and over again - e.g. I could work with inheritance, I could simply extract the methods in a class above where both controllers have access too...
What is the best practice here?
I don't like the "pull data for all views in group" approach, especially if you have to hit multiple tables and pull data you are not using in a particular set of data in a specific view.
One pattern that can work, depending on your need, is pull the common data and then use a decorator pattern to pull the additional data. But jumping to decorator can be dangerous, as it leads you to try to use it everywhere.
I like the "solve for each page and then refactor to patterns" approach, as you are not trying to then make things fit to the first pattern you find (ie, the hammer searching for nails methodology). But, if you have the pattern that shows a pattern like decorator solves the problem efficiently, then go that direction.
Hope this helps.
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.
First of all, I have been a php programmer for a long time and I am a mvc programmer newly. I did a few minor web sites that each have one or two controller at most. But I've started a website that will be very major web site. There will be a lot of data to pass to views.
Now, normally I try to use model approach every time instead of ViewBag or ViewData approach. If the view demands more data, then I change the model class and then recompile the project. Especially, if the topic is an index page, the data to pass to the index's view changes every time. In a big web site, I'll use a lot of partial view that uses different models. So every time, I will have to change the index's model to support those partial views in the index view. if I add a new partial view into index view, I have to add the partial's model into the index's model.
I implement an IndexModel class for an index view every time when I start a website. Then I add properties to this model every time when I add a new partial view to the index.
Now is this a correct approach or should I use ViewBag or ViewData for partials' models. I think the real question is when we should use the model approach and when we shouldn't...
If you share your experiences, I would be grateful.
The MVC approach you should use always, especially for simple sites, it's save your time and make application more understandable.
If you write something larger than two pages, you need to use MVVM pattern (growth of MVC), in that case you will escape from using "partial models" with ViewModels.
Model must contain only busines logic.
Be better if you will always use ViewModel (not a Model) for returning data from a view and pass it to view, because it provides some safety.
For facilitate the procedure of copy data from Models to ViewModels use the things like AutoMaper and EmitMapper.
ViewBag and ViewData you should use only for additional data's like item colections for DropDown, or some view-text like page title.
One more advantage of MVVM pattern is better testability. If you write and support really hugh site you may write tests for some responsible parts of code.
For more details you can look at google - MVVM, ASP-MVC.
If i something not understad in you question or miss, write it in the comment ("add comment" ref).
I personally prefer to keep my sites consistant and always use Model + Viewmodel (no matter how big the site is) despite the extra work (which isn't much anyway).
It helps with maintainability. I know where and how everything is stored and coded into the site.
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.
with model binding where you can build up an object to ship and bind to the view, is there any reason to ever use ViewData ?
I can't forsee an instance where I would use it unless I had static information coming in from a database for a page/master that then got displayed in say a <p> or some such.
If the page was a read only page that say returned a list of items and I also wanted to display text from a DB then I might use ViewData.
But that's kind of an exception. If I was returning a list of items from a DB along with some other stuff then I would create a Form View Model and simply include any other data in with it.
So rarely I guess is my answer here.
ViewData seems to exist as a simple, convenient approach to something that you really should do a syntactically cleaner way. The MVC equivalent of an ArrayList I suppose- works just fine but you'd be hard pressed to come up with a truly legitimate excuse for using it in good code.
One exception I can think of for using it would be including something dynamic in ALL of your pages that gets appended in an ActionFilter or base Controller class- for example "WebsiteTitle". Rather than attempting to tamper with the data being returned by a Controller action it might make more sense to include something like that in the ViewData collection- perhaps prefixed with some unique identifier to make it obvious it was being included outside the controller action. ViewData["Base_WebSiteName"], for example.
I am pretty new to MVC but what little I have done, I have written custom objects for all my views.
The only reason I could think of is to save time. You need to whip something up fast and maybe there are multiple objects of data on a page and something extra and you don't want to take the time to write an object putting it all together. Is this a good reason? In my opinion no.