32

I got a view List.aspx that is bound to the class Kindergarten

In the controller:

public ActionResult List(int Id)
{
  Kindergarten k = (from k1 in _kindergartensRepository.Kindergartens
                    where k1.Id == Id
                    select k1).First();

  return View(k);
}

That works.

But this doesn't

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(...)
{
  //...
  Kindergarten k = ...
  return RedirectToAction("List", k);
}

How should I redirect to the list view, passing k as the model?

Thanks!

Aximili
  • 28,626
  • 56
  • 157
  • 216

4 Answers4

56

I don't believe ModelBinding exists when using RedirectToAction. Your best options, however, is to use the TempData collection to store the object, and retrieve it in the following action.

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Add(...)
{
  //...
  Kindergarten k = ...
  TempData["KG"] = k;
  return RedirectToAction("List");
}

In your List Action

public ActionResult List()
{

   Kindergarten k = (Kindergarten)TempData["KG"];
   // I assume you need to do some stuff here with the object, 
   // otherwise this action would be a waste as you can do this in the Add Action
  return View(k);
}

Note: TempData collection only holds object for a single subsequent redirect. Once you make any redirect from Add, TempData["KG"] will be null (unless you repopulate it)

Omar
  • 39,496
  • 45
  • 145
  • 213
  • 1
    you shouldn't be using MVC like this. – eaglestorm Sep 27 '13 at 05:58
  • 2
    It implies there is to much logic in your actions. Business logic should be in a separate layer (services) and your action should call this logic and then redirect to the appropriate view. You shouldn't get into a position where you need to do the above if your app is well designed. – eaglestorm Sep 30 '13 at 02:15
  • 5
    Storing objects in memory doesn't mean you're app is not well designed. There are use cases for this: http://stackoverflow.com/a/1664269/160823. It may not be ideal in this exact implementation, but it's not inherently incorrect to use. – Omar Sep 30 '13 at 15:09
  • 2
    If MVC would allow use to send to the `public ActionResult MethodName(Model record)` overload of different controllers using the `RedirectToAction` method, I would be happy not to use this...but if I've done the work to load the Record in one controller, I don't want to pass an ID and then repeat the work in a second location. TempData gives me a suitable workaround. Thanks. – Mike_Matthews_II May 29 '15 at 17:42
  • ModelBinding does occur on a RedirectToAction – ManxJason Nov 14 '16 at 15:22
  • When multiple website instances are Load Balanced, theoretically every request might arrive to different instance. In such case, storing local state is a bad idea. Better to pass it as an argument or make it shared. – Illidan May 13 '17 at 04:34
27

I think you just need to call view like

return RedirectToAction("List", new {id});

with id you need to populate the Kindergarten.

Ashish
  • 328
  • 2
  • 7
18

I'm not sure you want to call RedirectToAction because that will just cause k to be set again.

I think you want to call View and pass in the name of the view and your model.

return View("List", k);
Brandon
  • 68,708
  • 30
  • 194
  • 223
  • Oh but what if the view is on another controller? – Aximili Feb 24 '10 at 06:20
  • When its looking for a View, it'll check the View\Controller\ folder, if it doesn't find it there, it checks the Shared folder. If you want to access a view across multiple controllers, put it in the Shared folder. – Brandon Feb 24 '10 at 06:22
  • Also, I haven't tested this, but I suppose you could also try giving it a direct path: return View("~/Views/Controller/List.ascx"). Although I believe using the shared folder is preferable. – Brandon Feb 24 '10 at 06:23
  • 2
    This is correct however the URL will still say Add, not List. – friggle Oct 16 '13 at 21:37
  • 2
    Also, this violates the Post-Redirect-Get pattern. If the page is refreshed after returning the view then the original Post is resent, which may cause problems. – big_tommy_7bb Feb 07 '14 at 12:01
1

As Brandon said, you probably want to use return View("List", Id) instead, but the problem you're having is that you're passing k, your model, to a method that accepts an int as its parameter.

Think of RedirectToAction as a method call.

Daniel T.
  • 37,212
  • 36
  • 139
  • 206