78

I want to know, there is any technique so we can pass Model as a parameter in RedirectToAction

For Example:

public class Student{
    public int Id{get;set;}
    public string Name{get;set;}
}

Controller

public class StudentController : Controller
{
    public ActionResult FillStudent()
    {
        return View();
    }
    [HttpPost]
    public ActionResult FillStudent(Student student1)
    {
        return RedirectToAction("GetStudent","Student",new{student=student1});
    }
    public ActionResult GetStudent(Student student)
    {
        return View();
    }
}

My Question - Can I pass student model in RedirectToAction?

Amit
  • 15,217
  • 8
  • 46
  • 68
  • 1
    Sure, that's a valid call. Doesn't it get routed? – Andrei V Mar 19 '14 at 12:23
  • 1
    I have tried this but model value was not found – Amit Mar 19 '14 at 12:25
  • Since the route dictionary deals with objects, try changing the `GetStudent` action to accept an `object` and inside cast it to `Student`. Another option would be to serialize it using JSON when passing it from `FillStudent`. – Andrei V Mar 19 '14 at 12:27
  • @AndreiV I am getting model value in `FillStudent` – Amit Mar 19 '14 at 12:28
  • It seems like this is a fundamental operation that should be supported by ASP.NET MVC out of the box, and yet still it isn't possible. I've had to resort to pulling values out of my model to create a route values object only to re-insert them into my model in the GET handler via extraction from multiple parameters. – AaronHolland Jul 03 '19 at 03:17

6 Answers6

88

Using TempData

Represents a set of data that persists only from one request to the next

[HttpPost]
public ActionResult FillStudent(Student student1)
{
    TempData["student"]= new Student();
    return RedirectToAction("GetStudent","Student");
}

[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
    Student std=(Student)TempData["student"];
    return View();
}

Alternative way Pass the data using Query string

return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});

This will generate a GET Request like Student/GetStudent?Name=John & Class=clsz

Ensure the method you want to redirect to is decorated with [HttpGet] as the above RedirectToAction will issue GET Request with http status code 302 Found (common way of performing url redirect)

Murali Murugesan
  • 22,423
  • 17
  • 73
  • 120
  • 12
    I don't want use `TempData`. I know we can achieve using TempData. But my question is different – Amit Mar 19 '14 at 12:38
  • @AmitAgrawal, check the second approach – Murali Murugesan Mar 19 '14 at 12:40
  • 2
    I know also approach2, but my question is different Can I achieve as my question __Yes/No__ – Amit Mar 19 '14 at 12:42
  • 3
    @AmitAgrawal, Simple `NO`. Check [Passing Data in an ASP.NET MVC Application](http://msdn.microsoft.com/en-us/library/dd394711(v=vs.100).aspx) – Murali Murugesan Mar 19 '14 at 12:43
  • 4
    This is an old thread, but I'd like to point out that 1) the GetStudent action does not need to have a parameter when using TempData 2) One must note that if this is to implement the PRG pattern, it still only partially solves the issue. On the second refresh of the view, TempData would be empty (by design)! – Sudhanshu Mishra Apr 01 '16 at 06:55
  • 2
    never use TempData. Imagine you have an application running in azure. you will end up having many instances for the application. and if ARR affinity is disabled you will end up first method is called by one instance to hold the data in tempData and second instance will receive the second request. You will pull your hair to figure out what is going on. So stay away from stateful solutions such as TempData or sessions. – akd May 29 '17 at 14:13
  • 2
    @akd Lol wut? Stay away from Sessions or TempData? The issue you're describing is only with Azure when ARR affinity is disabled. If you need a *stateful* solution (pretty much any web application that allows you to login), then TempData and Sessions are *absolutely* required. – Steve Bauman Jul 17 '18 at 17:29
45

Just call the action no need for redirect to action or the new keyword for model.

 [HttpPost]
    public ActionResult FillStudent(Student student1)
    {
        return GetStudent(student1); //this will also work
    }
    public ActionResult GetStudent(Student student)
    {
        return View(student);
    }
  • What is __return GetStudent(student1)__ – Amit Mar 19 '14 at 12:32
  • @AmitAgrawal it will call your GetStudent() Action – Vinay Pratap Singh Bhadauria Mar 19 '14 at 12:34
  • 9
    Action GetStudent has to return View 'GetStudent' with model student - worked for me - **return View("GetStudent", student)** – hotfusion Jan 10 '15 at 13:43
  • 2
    This answer doesn't work for me (page never changes), but hotfusions comment does. – Ravendarksky Mar 07 '16 at 11:27
  • 17
    Please note that while this works (with changes mentioned by @hotfusion) this is still not in line with PRG pattern. If the user hits F5, they will duplicate the original request again! – Sudhanshu Mishra Apr 01 '16 at 06:31
  • the difference is redirecttoaction sends user message saying I dont have what you are looking for. but here is the action that will help you to get what you need. Thats why user browser changes to new action. However if you just return the action as in this answer the user will never know which action handled the request. In stateless application it is better to always tell user basically use redirect to action option. – akd May 29 '17 at 14:13
  • 3
    this will show the url of the original request. That may not be desired. – John Lord May 09 '20 at 02:43
18

Yes you can pass the model that you have shown using

return RedirectToAction("GetStudent", "Student", student1 );

assuming student1 is an instance of Student

which will generate the following url (assuming your using the default routes and the value of student1 are ID=4 and Name="Amit")

.../Student/GetStudent/4?Name=Amit

Internally the RedirectToAction() method builds a RouteValueDictionary by using the .ToString() value of each property in the model. However, binding will only work if all the properties in the model are simple properties and it fails if any properties are complex objects or collections because the method does not use recursion. If for example, Student contained a property List<string> Subjects, then that property would result in a query string value of

....&Subjects=System.Collections.Generic.List'1[System.String]

and binding would fail and that property would be null

  • Thank you for this note on not including complex objects, Lists or collections to the Model when using RedirectToAction. This is what fixed it for me. – Mario Levesque Aug 21 '19 at 11:15
  • I second this. Thank you for the note on complex objects. We were trying to reject a huge model (about 200 fields) and ONE of them is a List(). We were getting about 20 cast string to int errors when redirecting, and it was not helpfully even showing what the error source was. – John Lord May 09 '20 at 02:42
0
  [HttpPost]
    public async Task<ActionResult> Capture(string imageData)
    {                      
        if (imageData.Length > 0)
        {
            var imageBytes = Convert.FromBase64String(imageData);
            using (var stream = new MemoryStream(imageBytes))
            {
                var result = (JsonResult)await IdentifyFace(stream);
                var serializer = new JavaScriptSerializer();
                var faceRecon = serializer.Deserialize<FaceIdentity>(serializer.Serialize(result.Data));

                if (faceRecon.Success) return RedirectToAction("Index", "Auth", new { param = serializer.Serialize(result.Data) });

            }
        }

        return Json(new { success = false, responseText = "Der opstod en fejl - Intet billede, manglede data." }, JsonRequestBehavior.AllowGet);

    }


// GET: Auth
    [HttpGet]
    public ActionResult Index(string param)
    {
        var serializer = new JavaScriptSerializer();
        var faceRecon = serializer.Deserialize<FaceIdentity>(param);


        return View(faceRecon);
    }
0
[NonAction]
private ActionResult CRUD(someModel entity)
{
        try
        {
            //you business logic here
     return View(entity);
       }                                
         catch (Exception exp)
         {
             ModelState.AddModelError("", exp.InnerException.Message);
             Response.StatusCode = 350;
             return someerrohandilingactionresult(entity, actionType);
         }
         //Retrun appropriate message or redirect to proper action
      return RedirectToAction("Index");   
}
  • because you are supposed to supply the error handler. However i am not sure how it is supposed to answer the problem. – John Lord May 09 '20 at 02:38
-3

i did find something like this, helps get rid of hardcoded tempdata tags

public class AccountController : Controller
{
    [HttpGet]
    public ActionResult Index(IndexPresentationModel model)
    {
        return View(model);
    }

    [HttpPost]
    public ActionResult Save(SaveUpdateModel model)
    {
        // save the information

        var presentationModel = new IndexPresentationModel();

        presentationModel.Message = model.Message;

        return this.RedirectToAction(c => c.Index(presentationModel));
    }
}
DiSaSteR
  • 608
  • 6
  • 11