How to Redirecttoaction in ASP.NET MVC Without Losing Request Data

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



Leave a reply



Submit