keep viewdata on RedirectToAction - asp.net-mvc

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateUser([Bind(Exclude = "Id")] User user)
{
...
db.SubmitChanges();
ViewData["info"] = "The account has been created.";
return RedirectToAction("Index", "Admin");
}
This doesnt keep the "info" text in the viewdata after the redirectToAction.
How would I get around this issue in the most elegant way?
My current idea is to put the stuff from the Index controlleraction in a [NonAction] and call that method from both the Index action and in the CreateUser action, but I have a feeling there must be a better way.
Thanks.

You can use TempData.
TempData["info"] = "The account has been created.".
TempData exists exactly for this situation. It uses Session as storage, but it will not be around after the second response.
From MSDN:
A typical use for a TempDataDictionary object is to pass data from an action method when it redirects to another action method. For example, an action method might store information about an error in the controller's TempData property (which returns a TempDataDictionary object) before it calls the RedirectToAction method. The next action method can then handle the error and render a view that displays an error message.

Use ViewData if your data should be accessible in View during "this" request. Use `TempData' if your data is for "next" request (for example POST-REDIRECT-GET design pattern).

If you need this more than once, a nice workaround would be creating ActionFilterAttributes which export/import the tempdata to viewdata and vice-versa. You can pass your ModelState in this way very nicely as well (demonstrated here - #13).
With a few adjustments to that piece of code you would have a clean solution, I think.

You could use the TempData controller property, but it has the disadvantage that it uses the session storage in the background. This means that you'll have extra work getting it to function on a web farm and you'll need to have sessions enabled in your application in the first place.
An alternative is to use cookies if you only need to transport a short message. This does require proper encryption of the cookie. Not relying on the TempData property also allows you to set messages in a non MVC context, for example in a classic ASHX page.
Take a look at FlashMessage which can save you some work implementing this yourself.

Since TempData appears to use storage, and any form of ITempDataProvider that is not "in-process", requires the object to be Serializable, TempData seems woefully inadequate in web farm situations... (ViewDataDictionary isn't itself serializable...) Does anyone have any suggestions for this?

The answer is TempData. The usage difference for clarification is as the following:
TempData = passing data from Action to another Action
ViewData = passing data from Action to a View

Related

What's the best way to pass a message from an action controller to another action controller

I'm currently using MVC5.
Imagine the scenario where one controller ActionA does its work and the redirects to another controller ActionB but also wants this second method to display a message on its related view.
If Controller ActionA sets the ViewBag.Message and then calls RedirectToAction, when ActionB starts, the value of that Message is gone.
What's the best way to pass a message from one action controller to another, without using Session ??
You can use TempData:
Action A:
TempData["Message"] = "Hi";
Action B:
var message = TempData["Message"];
Once you call the getter in Action B, the information will be automatically removed from memory.
This article is a really good explanation of the various persistence techniques available in ASP.NET MVC.
You say no session, but TempData can be a good place depending on what you're passing. It's essentially Session except that the item will be removed from Session once you've accessed it. TempData actually uses session by default unless you write your own provider.
Passing it as an option in the query string, or passing it as a parameter in the routing (similar to what AJ says)
Other than that you've got the standard run of the mill options that are provided in ASP.NET. HttpContext.Items or maybe HttpContext.Cache. But both of those are shared across the entire application domain so management can get tricky.
Remember, web is supposed to be stateless. So if it's really important for that message to get there, you probably want to put it in the URL somehow (query string or routing), or use a database.
I would put an optional argument on the method signature for ActionB, for example:
public ActionResult ActionB(string message = "")
Note that optional parameters need to be last in your parameters list.

asp.net mvc post data and page refresh (session variable vs tempData vs detect F5)

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

Passing a model into RedirectToAction()

I'm curious how this works. In MVC you can call View() and pass a model as a parameter, but RedirectToAction (one of its incarnations at least) takes a 'routeValues' object, which appears to be the closest match.
If your model is passed in this parameter will that model type be available in the subsequent action method? Or are there caveats involved that might prevent accurate translation in some circumstances?
If you need to pass in some-what complex objects to an action after a redirect, you probably want to use either a Session or TempData:
From "What is ASP.NET MVC TempData"
ASP.NET MVC TempData dictionary is used to share data between
controller actions. The value of TempData persists until it is read or
until the current user’s session times out
By default TempData uses a Session to persist the information, however, as with much of MVC, this is an extensibility point, where you can plug in a Cookie-based provider if you prefer.
You cannot pass a model object in there but you can pass individual properties that will map to a model in the action that you redirect to.
That works by building up the url to redirect to using the properties, and the model binder in the receiving action.
Redirect... methods cause client-side-and-back trip, so - no, the model will not be available.
I think this is what you want :
Save your model in a Tempdata
RequestModel rq = new RequestModel()
....assign something to your model..
TempData["request"] = rq;
return Redirect("RequestAcknowledgement");
Now create an Action Result for the view you are redirecting to and pass your TempData back to a model. Then return the model to a view.
public ActionResult RequestAcknowledgement()
{
RequestsModel request = (RequestsModel)TempData["request"];
return View(request);
}

Using Tempdata in ASP.NET MVC - Best practice

I am using ASP.NET MVC 3 to build a web application.
What I am trying to do is pass values between two controllers, though there are many ways to do this I am particular interested in using TempData for this.
public ActionResult Action1()
{
string someMessage;
Test obj = SomeOperation();
if(obj.Valid)
{
someMessage = obj.UserName;
}
else
{
someMessage = obj.ModeratorName;
}
TempData["message"] = someMessage;
return RedirectToAction("Index");
}
public ActionResult Index()
{
ViewBag.Message = TempData["message"]
return View();
}
So is the use of TempData here correct ? I mean under best programming practices is this correct way of using TempData ?
In what real time cases should TempData be used ?
Note : I have gone through the following links
When to use TempData vs Session in ASP.Net MVC
http://www.gregshackles.com/2010/07/asp-net-mvc-do-you-know-where-your-tempdata-is/
Thanks
TempData is a bucket where you can dump data that is only needed for the following request. That is, anything you put into TempData is discarded after the next request completes. This is useful for one-time messages, such as form validation errors. The important thing to take note of here is that this applies to the next request in the session, so that request can potentially happen in a different browser window or tab.
To answer your specific question: there's no right way to use it. It's all up to usability and convenience. If it works, makes sense and others are understanding it relatively easy, it's good. In your particular case, the passing of a parameter this way is fine, but it's strange that you need to do that (code smell?). I'd rather keep a value like this in resources (if it's a resource) or in the database (if it's a persistent value). From your usage, it seems like a resource, since you're using it for the page title.
Hope this helps.
Please note that MVC 3 onwards the persistence behavior of TempData has changed, now the value in TempData is persisted until it is read, and not just for the next request.
The value of TempData persists until it is read or until the session
times out. Persisting TempData in this way enables scenarios such as
redirection, because the values in TempData are available beyond a
single request.
https://msdn.microsoft.com/en-in/library/dd394711%28v=vs.100%29.aspx
Just be aware of TempData persistence, it's a bit tricky. For example if you even simply read TempData inside the current request, it would be removed and consequently you don't have it for the next request. Instead, you can use Peek method. I would recommend reading this cool article:
MVC Tempdata , Peek and Keep confusion

Where to initialize TempData

I need a variable that will be used everywhere (controller, view, master page, ...). I was thinking of putting it in the TempData. Where is the best place to put an object there?
I thought of Page_Load but that's done after the controller.
I thought of the controller Initialize but the TempData seems to be cleared after that.
I couldn't use a session because the data could change on every request. I decided to initialize everything in the OnActionExecuting of the controller and it's working great.
You should use a Session variable rather than TempData. Variables stored in TempData will be destroyed after one request: Difference Between ViewData and TempData?
Here is a link documenting the various Client and Server side storage options in Asp.net
http://www.dotnetfunda.com/articles/article61.aspx

Resources