How to RedirectToAction in ASP.NET MVC without losing request data
The solution is to use the TempData property to store the desired Request components.
For instance:
public ActionResult Send()
{
TempData["form"] = Request.Form;
return this.RedirectToAction(a => a.Form());
}
Then in your "Form" action you can go:
public ActionResult Form()
{
/* Declare viewData etc. */
if (TempData["form"] != null)
{
/* Cast TempData["form"] to
System.Collections.Specialized.NameValueCollection
and use it */
}
return View("Form", viewData);
}
RedirectToAction() loss request data
The correct design pattern is not to redirect in case of a validation error bu render the same form again. You should redirect only if the operation succeeds.
Example:
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
// some validation error occurred => redisplay the same form so that the user
// can fix his errors
return View(model);
}
// at this stage we know that the model is valid => let's attempt to process it
string errorMessage;
if (!DoSomethingWithTheModel(out errorMessage))
{
// some business transaction failed => redisplay the same view informing
// the user that something went wrong with the processing of his request
ModelState.AddModelError("", errorMessage);
return View(model);
}
// Success => redirect
return RedirectToAction("Success");
}
This pattern allows you to preserve all model values in case some error occurs and you need to redisplay the same view.
Is it possible to RedirectToAction passing data without using parameters in an ASP.NET MVC project?
You can't send data with a RedirectAction
. That's because you're doing a 301
redirection and that goes back to the client.
So better use TempData
Assuming you will have model to createperson
with following properties:
public class CreatePersonData
{
public string name {get; set;}
public string address {get; set;}
}
Now fill the model
and store in TempData
CreatePersonData person=new CreatePersonData();
person.name="SomeName";
person.address="SomeAddress";
TempData["person"]=person;
return RedirectToAction("CreatePerson", "Home")
Now while receiving just receive it from tempdata
and pass the filled model
to the view
public ActionResult CreatePerson()
{
CreatePersonData person=new CreatePersonData()
var loadPerson= TempData["person"];
person = loadPerson;
return View(person);
}
UPDATE
As @StephenMuecke made a point of loosing data with TempData
you might need to use .Keep
or .Peek
with TempData to retain the value for future requests
Ex:
with .Peek
//PEEK value so it is not deleted at the end of the request
var loadPerson= TempData.Peek("person");
or with .Keep
//get value marking it from deletion
var loadPerson = TempData["person"];
//later on decide to keep it
TempData.Keep("person");
or as @Stephen said just pass the id
and select the user
from database
Ex:
return RedirectToAction("CreatePerson", "Home", new { ID = User.ID });
Now in your CreatePerson
ActionResult
just get it from db as below:
public ActionResult CreatePerson(int ID)
{
CreatePersonData person=new CreatePersonData();
var user=(from u in tbl_user select u where u.ID=ID);
person.name=user.name;
person.address=user.address;
return View(person);
}
UPDATE 2
You can combine both of the above approaches like storing data in TempData
and passing the ID
with routeValues
and check if TempData
isn't null then fallback to retrieval of data using ID
approach.
Ex:
public class CreatePersonData
{
public string Id{get; set;}
public string name {get; set;}
public string address {get; set;}
}
public ActionResult CreatePerson(int ID)
{
CreatePersonData person=new CreatePersonData();
var loadPerson=(CreatePersonData)TempData.Peek("person"); //cast the object from TempData
if(loadPerson!=null && loadPerson.Id==ID)
{
person=loadPerson;
}
else
{
var user=(from u in tbl_user select u where u.ID=ID);
person.name=user.name;
person.address=user.address;
}
return View(person);
}
Redirect to action and need to pass data
EDIT: Sorry, didn't originally see your note about not wanting to use TempData.
In a nutshell - do you want your message to reappear if the client refreshes/reloads the page they've been redirected to?
If you do, then use the querystring, something like:
return(RedirectToAction("Index", new { message = "hi there!" }));
and then either define
public ActionResult Index(string message) { }
or explicitly pull out Request.QueryString["message"] and pass it to the View via ViewData in the usual way. This will also work on browsers that aren't accepting cookies from your site.
If you DON'T want the message to display again, then ASP.NET MVC 1.0 provides the TempData collection for this exact purpose.
TempData property values are stored in session state until the next request from the same browser, after which they are cleared - so if you put something in TempData immediately before returning RedirectToAction, it'll be available on the result of the redirect but will be cleared immediately afterwards.
Here's a simple change to the HomeController in the ASP.NET MVC startup project:
public ActionResult Index() {
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(string submitButton) {
TempData["message"] = "You clicked " + submitButton;
return(RedirectToAction("Index"));
}
public ActionResult About() {
return View();
}
and the corresponding view /Views/Home/Index.aspx should contain something like this:
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<% if (TempData["message"] != null) { %>
<p><%= Html.Encode(TempData["message"]) %></p>
<% } %>
<% using (Html.BeginForm()) { %>
<input type="submit" name="submitButton" value="Button One" />
<input type="submit" name="submitButton" value="Button Two" />
<% } %>
</asp:Content>
You'll notice the TempData message is displayed immediately following a POST-REDIRECT-GET sequence, but if you refresh the page, it won't be displayed again.
Note that this behaviour has changed in ASP.NET MVC 2 - see "Passing State between Action Methods" in this article for more information.
keep viewdata on RedirectToAction
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.
RedirectToAction and pass a value?
You can use TempData
variable.
public ActionResult Index()
{
TempData["AfterRedirectVar"] = "Something";
RedirectToAction("Redirected", "Auth", new { data = "test" });
}
public ActionResult Redirected(string data = "")
{
string tempVar = TempData["AfterRedirectVar"] as string;
return View();
}
This link could be helpful.
ASP .NET Core MVC: What happens to a request on RedirectToAction
As mentioned, RedirecToAction
will cause the browser to make a new request, and when that new request comes in, it will create a totally new HttpContext
. As mentioned, To pass data between the two requests, you can use the query string, session or cookies. But there is another option to consider.
TempData
Data can be passed from one request to another via the TempData
collection which is accessible in the controller action method. The TempData
collection was specifically designed for passing data from one request to another. The beauty of TempData
is that the lifetime of an object placed in TempData
is exactly one additional request. So anything placed in TempData
in request 1 will be there for request 2 but then be automatically removed from TempData
at the conclusion of request 2. This makes TempData
perfect for passing data from one request to another without having to disclose that information in a query string or possibly forgetting it in session and bloating the session object.
Related Topics
Why Aren't Variables Declared in "Try" in Scope in "Catch" or "Finally"
What Are Checked Exceptions in Java/C#
Drag and Drop to Desktop/Explorer
How to Add a .Dll Reference to a Project in Visual Studio
Page.Datacontext Not Inherited from Parent Frame
How Does Creating a Instance of Class Inside of the Class Itself Works
How to Upload a File to an Sftp Server in C# (.Net)
How Does Hashset Compare Elements for Equality
How to Pass Constructor Parameters to Unity's Resolve() Method
Why New Fb API 2.4 Returns Null Email on MVC 5 with Identity and Oauth 2
Standardoutput.Readtoend() Hangs
Prevent Property from Being Serialized in Web API
Simple Injector Unable to Inject Dependencies in Web API Controllers
How to Tell JSON.Net Globally to Apply the Stringenumconverter to All Enums