4

how can i send data between actions with redirectAction??

I am using PRG pattern. And I want to make something like that

[HttpGet]
    [ActionName("Success")]
    public ActionResult Success(PersonalDataViewModel model)
    {
        //model ko
        if (model == null)
            return RedirectToAction("Index", "Account");

        //model OK
        return View(model);
    }

    [HttpPost]
    [ExportModelStateToTempData]
    [ActionName("Success")]
    public ActionResult SuccessProcess(PersonalDataViewModel model)
    {

        if (!ModelState.IsValid)
        {
            ModelState.AddModelError("", "Error");
            return RedirectToAction("Index", "Account");
        }

        //model OK
        return RedirectToAction("Success", new PersonalDataViewModel() { BadgeData = this.GetBadgeData });
    }
Pedre
  • 446
  • 1
  • 8
  • 16
  • Regards your code, are you getting any errors? You look to be passing the data already, so are you getting any exceptions? – Jason Evans May 25 '12 at 09:50
  • In your redirect to action, change `BadgeData` assignment to be `BadgeData = model.GetBadgeData`? Otherwise, what is `this`? – Mathew Thompson May 25 '12 at 09:51

3 Answers3

9

When redirect you can only pass query string values. Not entire complex objects:

return RedirectToAction("Success", new {
    prop1 = model.Prop1,
    prop2 = model.Prop2,
    ...
});

This works only with scalar values. So you need to ensure that you include every property that you need in the query string, otherwise it will be lost in the redirect.

Another possibility is to persist your model somewhere on the server (like a database or something) and when redirecting only pass the id which will allow to retrieve the model back:

int id = StoreModel(model);
return RedirectToAction("Success", new { id = id });

and inside the Success action retrieve the model back:

public ActionResult Success(int id)
{
    var model = GetModel(id);
    ...
}

Yet another possibility is to use TempData although personally I don't recommend it:

TempData["model"] = model;
return RedirectToAction("Success");

and inside the Success action fetch it from TempData:

var model = TempData["model"] as PersonalDataViewModel;
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
2

You cannot pass data between actions using objects, as Darin mentioned, you can only pass scalar values.

If your data is too large, or does not consist only of scalar values, you should do something like this

[HttpGet]
public ActionResult Success(int? id)
{
    if (!(id.HasValue))
        return RedirectToAction("Index", "Account");

    //id OK
    model = LoadModelById(id.Value);
    return View(model);
}

And pass that id from RedirectToAction

    return RedirectToAction("Success", { id = Model.Id });
archil
  • 39,013
  • 7
  • 65
  • 82
0

RedirectToAction method returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action. So you can not pass complex objects like you calling other methods with complex objects.

Your possible solution is to pass an id using with the GET action can build the object again. Some thing like this

[HttpPost]
public ActionResult SuccessProcess(PersonViewModel model)
{
  //Some thing is Posted (P) 
  if(ModelState.IsValid)
  {
    //Save the data and Redirect (R)
    return RedirectToAction("Index",new { id=model.ID});
  }
  return View(model)
}

public ActionResult Index(int id)
{
  //Lets do a GET (G) request like browser requesting for any time with ID
  PersonViewModel model=GetPersonFromID(id);
  return View(id);
}

}

You can keep data (The complex object) between This Post and GET request using Session also (TempData is internally using session even). But i believe that Takes away the purity of PRG Pattern.

Shyju
  • 214,206
  • 104
  • 411
  • 497
  • But you are doing return View(model) in the post Action. Is it correct with the prg pattern? – Pedre May 25 '12 at 10:03
  • @Pedre: Return View will be executed if the ModelState.IsValid property returns false. That means there is some validation errors in the form. So we need to show the form again with the values user entered and the error messages. So it is absolutely correct to do so. – Shyju May 25 '12 at 10:25
  • And then What happens if I press F5?... would I resubmit post request? – Pedre May 25 '12 at 11:24
  • I think in this case we must to redirect to GETaction and to use ActionFilters to send ModelState [link](http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx#prg) – Pedre May 25 '12 at 11:29
  • @Pedre: If you press F5, it is again the same GET request. So It will work fine ( read the id and get data and show the data). That is how PRG works. Post- Redirect- GET. When you press f5, It is executing the GET part again. It will not resubmit the post request again. – Shyju May 25 '12 at 11:46
  • @Pedre If your GET is succesfully executed, Then when you press F5. It is a new GET request from the browser to the server. Not POST – Shyju May 25 '12 at 14:39