0

I have two actions in my controller when a user call one i need to redirect it to another one and pass a complex object :

first action :

public virtual ActionResult Index(string Id) {
            var input = new CustomInput();
            input.PaymentTypeId = Id;
            return RedirectToAction(MVC.Ops.SPS.Actions.Test(input));
        }

second action :

public virtual ActionResult Test(CustomInput input) {
            return View();
        }

The probelm is that the input arrives null at the second action. how can i solve it?

Anton Selin
  • 3,462
  • 6
  • 19
  • 23
  • possible duplicate of [Passing data between different controller action methods](http://stackoverflow.com/questions/15385442/passing-data-between-different-controller-action-methods) – Rob Tillie Jan 15 '15 at 09:28
  • This is entirely unnecessary. Just pass the `Id` from the `Index()` method to the `Test()` method - `return RedirectToAction("Test", new { ID = Id });` and change method to `public ActionResult Test(int ID)` then create the new `CustomInput` in the `Test()` method. –  Jan 15 '15 at 11:33
  • If you are not really concerned about what url will display in browser.. you can just try **return Test(input);** and it will work as expected. – K D Jan 15 '15 at 11:36

2 Answers2

3

You can solve this using temp data to temporarily hold a value from which the second method retrieves that value.

public virtual ActionResult Index(string Id) 
{
    var input = new CustomInput();
    input.PaymentTypeId = Id;
    TempData["TheCustomData"] = input; //temp data, this only sticks around for one "postback"
    return RedirectToAction(MVC.Ops.SPS.Actions.Test());
}


public virtual ActionResult Test()
{
        CustomInput = TempData["TheCustomData"] as CustomInput;
        //now do what you want with Custom Input
         return View();

}

You can keep your tempData going so long as it is never null using the .keep() method like this,

    if (TempData["TheCustomData"] != null)
        TempData.Keep("TheCustomData");
Master Yoda
  • 4,334
  • 10
  • 43
  • 77
0

I want to make sure that you know that RedirectToAction creates new HTTP request so this create another GET and all you can pass is RouteValueDictionary object which is like having query string parameters which is list of key and value pairs of string. That said, You can't pass complex object with your way of code however the TempData solution mentioned by @kyleT will work.

My recommendation based on your code is to avoid having two actions and redirect from one another unless you are doing something more than what you have mentioned in your question. Or you can make your Test action accepting the id parameter the your Index action will contain only RedirectToAction passing the id as route parameter.

Edit: Also, If you have no primitive properties you can pass your object like the following (Thanks to @Stephen Muecke)

return RedirectToAction("Test",(input);
Hossam Barakat
  • 1,399
  • 9
  • 19
  • You **can** pass a complex object (internally the method generates a `RouteValueDictionary` based on the `.ToString()` value of each property in the model) but it only works for value types (complex objects and collections are not passed) –  Jan 15 '15 at 10:36
  • @StephenMuecke, good point, I have edited my answer to show it as example – Hossam Barakat Jan 15 '15 at 11:25
  • You don't need the cast - it's can be just `RedirectToAction("Test", input);`. But its not recommended anyway and creates an ugly route - and if there are a lot of properties you would soon exceed the query string parameters. –  Jan 15 '15 at 11:29
  • @StephenMuecke, I totally agree with you, That's why I have recommended to go for solution other than using 2 action methods – Hossam Barakat Jan 15 '15 at 11:32
  • Agreed - I don't get what OP is trying to achieve with the code in question :) –  Jan 15 '15 at 11:37