I am using in my views (asp mvc3/razor cshtml) references to the Request object (eg, #Request.Params["Name"]). Do you think this is a very bad practice? Should I rewrite the value in the controller Request.Params ["Name"] to ViewBag.Name and then use it in the view (#ViewBag.Name)?
Best practice is to use a model class. An instance of the model class is created or updated in your controller. Then the controller displays a strongly-typed view.
So I'd avoid direct access to the request from the view as well as the use of the view bag.
Should I rewrite the value in the controller Request.Params ["Name"] to ViewBag.Name and then use it in the view (#ViewBag.Name)?
Yes. You will avoid runtime errors if "Name" does not exist.
The IDE will not warn you of the NullReferenceException about to be thrown with the following code.
#Request.Params["Fake"].ToString()
Of course, you'll have to be careful about ViewBag.Fake being null as well.
I like to use the viewbag to store things not related to the model, for example if I have a dropdown containing locations. I like to store only the id of the selected location on the model and the locations in the viewbag, since is not needed to create a contact. I think that's the purpose of the viewbag.
For me the model is a bag or properties used in business operations, for example if I have a customer creation view using a NewCustomerModel, I don't wanna pollute my model with things like a IList<CustomerType> AND a SelectedCustomerTypeId property. I just want the second since is the one imma use to create the customer.
Related
In asp.net mvc, why is ViewBag called ViewBag?
I'm looking for the history or reason why it's called ViewBag over some other name.
ViewBag is a dynamic mapping of the ViewData dictionary. It's called a "bag" because there's no order or sequence to it.. it's just a bunch of data accessible from a dynamic property, much like if you had a bag of stuff.
The underlying ViewData has order to it, but when it's mapped to the dynamic collection it loses that order.. thus it's a bag.
See a definition here:
http://www.cs.miami.edu/~geoff/Courses/MTH517-00S/Content/ArrayBasedADTs/BagsStacksQueues.html
Its a bag full of information which is made available to the view.
It enables you to dynamically share values from the controller to the view. It is a dynamic object which means it has no pre-defined properties. You define the properties you want the ViewBag to have by simply adding them to the property. In the view, you retrieve those values by using same name for the property.
Which is better from design and coding point of view: accessing session data in the view directly or loading them in the controller and passing them to the view using a viewbag?
MVC wont really care if you do something in your controller or your views but i agree with shaftpolls for not hurting the mvc pattern. Since Session is already inside the ViewData wrapper, you can access it directly in the View.
Be aware, that the Session object should only contain simple, non-sensitive data like user picked language, or custom ui-colorsheme.
If you really need to use Session, you should get that data on the server side and then pass it to the View using Strongly Typed properties in a View Model rather than using the ViewBag.
So let's say you have a property on your view model which is of type IENumerable<SelectListItem> and inside your view you will use the strongly typed version of the Html.DropDownListFor helper to bind to the model this way:
#Html.DropDownListFor(x => x.ProductId, Model.Products)
The best thing to do is access the session in the controller. Why:
Performance. You have fine control of how to access the Session object. If you need to read just properties of the session, then specify that you need read-only access to the session, MVC won't block the session, you'll get more performance.
Pureness. In a pure MVC scenario, the view knows only about the model. So any value that you care about in your session must be passed as part of the model.
Is there a option to pass data between Model and view in ASP.NET. If it can be accomplished how? This was asked in an interview !!!
Yes... well, the view is either typed, which means the object that represents the model is directly accessible, or the controller returns a ViewBag with data or anything else the view needs to render. That's the whole point of the model-view part of the pattern.
The whole point of MVC is that the data(Model) should be shown to user (View) by use of Controller. Even if the view is typed, your still need the model to bind to it. Even to create a ViewBag, you need the controller action to fill it...
We are adding tooltips to our ASP.NET MVC product, and we are getting the text from our database (technically, from a cached copy of the data). To do so, we created an Html Helper method:
<%=Html.Tooltip(Model.GetTooltipText(Tooltips.ClientPage.StartDateId))%>
The GetTooltipText method is in our BaseViewModel, and simply uses the passed in Id to fetch the tooltip from cache.
Would this be considered a bad design? What other alternatives would we have?
Thanks!
Its probably a better idea to grab all the Tooltip's in one hit and put them in some sort of strongly-typed collection (perhaps a Dictionary<id,string>), cache all of that in your service layer.
Then you could put this in a ViewModel and pass it through to your strongly-typed view.
In your View you could simply access that strongly-typed collected via the Model based on the unique key?
I.e.
<%: Model.Tooltips[SomeDateId] %>
In my app I have a criteria builder section that's built using jquery and is pitched back to the controller in a form post and picked up as IList by the model binder as suggested in Phil's post here: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
A really simple way that I'm persisting the criteria across posts is re-delivering the IList object to the view. I'm using a DisplayFor() template for this object, but because it's a list I need to know the index # inside of the template.
I'm hoping there's a context value somewhere.
Well, I couldn't find any information on that kind of meta data, so I had to crud up my view model to contain that index and another property. So now it's a simple Model.IndexItem on the template that returns it's order in the entire collection.