Good morning,
I have a view that display's search results for customers. On top of the view i have a filter that has a few checkboxes. The user can select multiple checkbox items and press the filter results button. When the user presses the button it calls an action that filters the result. The page is also refreshed. My question now, how can i make the page remember what checkboxes are checked. Because when the results are returned the filter elements are reset.
Thanks in advance.
you can use TempData. TempData VS ViewBag VS ViewData
you used ViewData, After the redirect, the ViewBag & ViewData objects are no longer available
TempData is also a dictionary derived from TempDataDictionary class
and stored in short lives session and it is a string key and object
value. The difference is that the life cycle of the object. TempData
keep the information for the time of an HTTP Request. This mean only
from one page to another. This also work with a 302/303 redirection
because it’s in the same HTTP Request. Helps to maintain data when you
move from one controller to other controller or from one action to
other action. In other words when you redirect, “Tempdata” helps to
maintain data between those redirects. It internally uses session
variables. Temp data use during the current and subsequent request
only means it is use when you are sure that next request will be
redirecting to next view. It requires typecasting for complex data
type and check for null values to avoid error. generally used to store
only one time messages like error messages, validation messages.
TempData["CheckedList"] = YourCheckBoxListValues; //in your controller
in your View
#{
var tempchkboxList = TempData["CheckedList"] as yourStronglyTypeClass;
//or
var tempchkboxList = TempData["CheckedList"].ToString();
}
Depends on how long the input criteria should be remembered.
You could also save it in your session via Session["customerCriteria"] = yourCriteria, but it would be easier to give an example if you had provided some code.
You can keep your selected/checked checkbox details in session variable when you post the form (by clicking on the search button). In the HttpPost action,read the checkboxes which were checked and add that to a collection property of your viewmodel and send it back to the view. set the session variable values to null once you are done with it (after reading). in the view, use your viewmodel value to set the checked status of those checkboxes.
Another option is using ajax. When you click on search.Read your search criteria and make an ajax request to the action method. Return a partial view back and update only the div/table which shows the results of the search.
Related
i am teaching myself MVC and am struggling to work out the best solution to my problem. I have a search controller with a large amount of input fields. I will also have multiple overloads of the search fields eg basic search advanced search searchByCategory etc.
When the search form is posted i redirect to another action that displays the search results. If i press f5 the get action is fired again as opposed to the search results being refreshed in the action that my post redirects to. Ideally i would like to redirect to a search results Action Method without using the query string, or detect when refresh is hit and requery the database and just use different actions within the same search controller. I have read a lot of posts about this and the only 2 solutions i can find is using a session variable or TempData.Can anybody advise as to what is the best practice
From the Comments
Most of the time I prefer to use TempData in place of QueryString. This keeps the Url clean.
Question
Can anybody advise as to what is the best practice
Answer
Once the data is sent to Action Method to get the results from Database after then As per my knowledge you can use TempData to store the posted data. It is like a DataReader Class, once read, Data will be lost. So that stored data in TempData will become null.
var Value = TempData["keyName"] //Once read, data will be lost
So to persist the data even after the data is read you can Alive it like below
var Value = TempData["keyName"];
TempData.Keep(); //Data will not be lost for all Keys
TempData.Keep("keyName"); //Data will not be lost for this Key
TempData works in new Tabs/Windows also, like Session variable does.
You could use Session Variable also, Only major problem is that Session Variable are very heavy comparing with TempData. Finally you are able to keep the data across Controllers/Area also.
Hope this post will help you alot.
I think there is no need to even call Get Method after performing search although its good habit in case of if your are performing any add/update/delete operation in database. But in your case you can just return the View from your post method and no need to store data in tempdata or session until you really don't need them again. So do something like this:
[HttpPost]
public virtual ActionResult PerformSearch(SearchModel model)
{
// Your code to perform search
return View(model);
}
Hope this will help.
Hi thanks
I have had a chance to revisit this. the problem was i neglected to mention that i am using jQuery mobile which uses Ajax by default even for a normal Html.BeginForm. I was also returning a view which i have since learned will not updated the URL but only render new html for the current controller. my solution is to set the action, controller and html attributes in the Html.Beginformas follows :
#Html.BeginForm("Index", "SearchResults", FormMethod.Post, new { data_ajax = "false" })
inside the parameters for the index action of the searchResults controller I have a viewModel that represents the fieldset of the form that i am posting. The data-ajax="false" disables the Ajax on the form post and MVC takes care of matching the form post parameters to my model. This allows the url to update and when i press f5 to refresh the controller re-queries the database and updates the search results.
Thanks everybody for your help. I was aware of TempData but it is good to know that this is preferred over session data so i voted up your answer
I am displaying a value on my MVC view using a query string. For example ..
in my view I have:
<h3>Selected Game <%=Request["GameId"]%> </h3>
This displays the gameid selected by user on the view (via a query string)
Now I want to be able to use this value displayed on the view and run a query in the controller/service layer code. How can I pass this value to the controller.
You can access the Request the same way from the controller.
string gameid = Request["GameId"];
I would caution you, however, about trusting values you get from the request. This is where hackers like to strike, by entering their own values, which may not even be numbers.
Validate all data you get from the client, including querystring parameters.
You can't pass it to the same controller .. The view is already rendered. You seem to know about ajax, so it's just a simple matter of making another request. Make an ajax request to the controller in question with the GameId parameter.
I'm in serious need of passing url params with View class. Here's code:
if (!ModelState.IsValid)
{
return View(model);
}
This should not only return model based view, but also add specific param to URL (param won't change view details, but is needed as it's one of few automatically generated SessionKeys (one for each tab/window used to view app) and I know no other way to get to it, different than passing as param (it can't be generated everytime, 'cos params will change; it can't be global variable because it'll reset its value each refresh; it can't be static, because static is evul).
Oh this action is called with use of form and submit button, not actionLink or something like this.
EDIT1: I need params to stay in URL after refresh, or I need some other form of keeping data that persists through refresh/validation fail.
If I understand you correctly you have data that you need to use in generating Urls on your page? This just forms part of your ViewModel - or at least it should, since it's data that the View needs in order to render.
You can use ViewData to add any extra data that isn't part of your view model. Or, better still, add the data as members to it. Equally, if different views with different View Models require this data, add a ViewModel base class and derive from that so you can share that data.
use
RedirectToAction("actionName","controller",
new RouteValueDictionary(new {param1="value",param2="value2"});
or you can use hidden field to store the values in your page and then pass this down as and when you need them..
I'm working on my first MVC application, still figuring it all out.
I have a viewmodel which, at this point, is identical to my domain object. My controller builds the viewmodel and passes it to a view. The view only displays a some of the properties because I don't want primary and/or foreign keys displayed for the user yet, in the case of a primary key, I need to have the data in order to update / delete the database.
It appears that unless I use a viewmodel property in the view, it is set to default values (0 for numeric value types and null for reference types) when I pass the viewmodel back. Is this correct behavior?
I confirmed the viewmodel passed to the Edit view does contain all the properties (as I would expect).
The question - Once a view is rendered, what happens to the viewmodel? If my viewmodel contains properties that are not used in the view, do their values just disappear? For example, when I click the Edit actionlink to fire the Edit action on the controller, the viewmodel that gets passed to the action does not contain any properties unless they are visible on the screen. Why?
BTW, this is ASP.NET MVC 4 RC.
It appears that unless I use a viewmodel property in the view, it is
set to default values (0 for numeric value types and null for
reference types) when I pass the viewmodel back. Is this correct
behavior?
Yes, when you invoke a controller action you need to pass all the properties that you want to be bound in the request. So for example if you are using a html <form> to call the action you need to use input fields. You could use hidden fields but they must be present, otherwise nothing is sent to the controller action
The question - Once a view is rendered, what happens to the viewmodel?
It falls out of scope and is eligible for garbage collected.
If my viewmodel contains properties that are not used in the view, do their values just disappear?
Absolutely. But even if you use those properties inside the view they disappear. For example if you only display the values inside the view but do not use input fields to send them back to the server when the form is submitted they will be gone as well.
For example, when I click the Edit actionlink to fire the Edit action
on the controller, the viewmodel that gets passed to the action does
not contain any properties unless they are visible on the screen. Why?
Because the view model no longer exists. It's gone and garbage collected. That's how the HTTP protocol works. It's stateless. Nothing is persisted between the requests. You will have to include whatever properties you want to be populated in the request either as POST form values or as query string parameters if you are using action links or whatever.
If the user is not supposed to modify those values inside the view you could then simply pass an id to the controller action which will allow for this controller action to retrieve the model from wherever it is stored (a database or something) using this id.
If your properties are in any helper methods which generates the input HTML element inside a form, It will be available in your HTTPost action method when you submit the form. If you are simply displaying it in a div/span , it is not going to get you the property values. That is how MVC model binding works.
Expect the values in your HttpPOST action if you use these HTML helpers
#Html.TextBoxFor
#Html.DropDownFor
#Html.EditorFor
#Html.HiddenFor
Dont expect the values if you use these
#Html.DisplayFor
How do I can persist data in MVC Razor without using TempData between requests?
I see when we can use TempData from this, but don't want to TempData as it creates a state on the machine.
Thanks, Anish
EDIT: I want to persist the previous sort direction in a View page where a user is allowed to sort fields such as Name, Age etc.
FIX: I fixed it using ViewBag. Previous sort field/direction sent to View from Controller using ViewBag and then passed it back as query string in the next click.
Good FIX: I handled the everything in .js file such as checking and then in setting the previous sort field and previous sort dir in Controller.
This is what I finally did. I used ViewBag to send previous details to ViewPage and did the validation in a .js based on the current user action and passed it back to the controller in form-data.
Maintaining State in client page is something which is breaking the concept of HTTP which is stateless. Why do you want to maintain state ? If you are looking for some solution for Passing some data from your controller action to corresponding view, i would suggest you to go with a ViewModel where you fill the data for the dropdown and send that ViewModel object to the strongly typed view. You will have your data available there. Also you should grab data from your DataLayer ( from tables/ or Cache or etc..) in every request if you want some data.
You may pass a relevant id in the query string to get the corresponding data.
As RTigger mentioned, you may store some data in session. That will be available across all the pages till the life time of that session.
I haven't done a lot of ASP.NET MVC 3 recently, but I think the only real way you can persist data across requests is either with session state, cookies, or by posting data to the server every request.
ViewData, ViewBag, and TempData are all effectively killed at the end of each request, whereas session state, cookies, and post data is made available at the beginning of every request based on information from the client browser.
What particular scenario are you trying to persist data for?
You could pass those values as query string parameters when redirecting.
You can set parameters to hidden input fields if you post the form. But if you gonna call action by HTTPGET then you can pass values by using QueryString parameters.