I am using PRG pattern for form submission in mvc. But In most of the sites suggested me to use temp data in PRG instead of view data. But I don't know how to judge this.
View bag and view data Lives only during the current request from controller to view and Temp data also Lives only during the current request from action to action or controller to another controller.
Can we use View data instead of Temp data for PRG pattern ?
Why we need to use temp data instead of view bag, view data ?
in prg pattern you redirect after a successful form submission wheres as ViewData is saved after a redirect whereas temp is saved using the same storage that session uses.
what i mean by this is if you have saved any data in ViewData like
ViewData.CustomerId = 67; it wont be available to you after the form is submitted and the user is redirected to another action/controller
where as if you save data in TempData it will be saved for at least the time where you access it once
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
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.
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.
How can I pass a viewmodel to a view without the model's data showing up in the URL?
public ActionResult MyView(MyModel model)
{
model.memberId = "Secret Id"
return View("MyView", model)
}
URL shows up as
http://localhost:1234/MyView?memberId=Secret Id
The data is not critically secret but having it show up in the URL is not really acceptable.
I don't know what you are up to, you should never set anything secret in a viewmodel - because the viewmodel is as the name says to be seen...
But to answer your question: To avoid the memberId occuring in the url you can submit your form by post - but that is of course not secure as well.
You should better store that in the session for example.
As already mentioned, view models are exactly that - models for your view. You should never store any data in a view model that should not be exposed to the client in one shape or form (whether it be a hidden form value, part of the url or in an ajax call).
If you really need data to be secret, and you want to pass it between actions, use TempData, or the ASPNet Session. That way, it goes nowhere near the client.
I wrote a CAPTCHA generator that uses TempData to store the actual CAPTCHA string, as sending it to the client would mean that any automated system would be able to read the string. I'd recommend using TempData over the session, though, as it's only persisted for one request - whereas the session needs managing by yourself.
TempData["MyDataIdentifier"] = "MyObjectOrValue";
am new to MVC but have a Q about PartialViews. I have two PartialViews accessing Model Data from the ParentView (Model Data passed through via the ParentView's Controller). The first PartialView is used to update (add/delete values) Model Data to the database. The second PartialView generates a document based on the ParentsView Model Data. The problem is that if the data is changed in the database by the first PartialView then the ParentViews Model Data is now out of date and hence the Second PartialView (referencing the ParentsView Model Data) is now working with out of date data.
I realise the above should be re-engineered to to better suite, however is there a way to make the updated Model Data available at the ParentView level for the second PartialView to reference?
Usually in order to update something into the database an HTTP request is sent to the server and the controller action performs the update and renders a view meaning that the whole page is reloaded and the model data updated.
If you perform an AJAX request to update the database then you might need to update the second partial view as well so that changes are taken into account.