I'm rendering a common Log-In form using Html.RenderAction, on every page of my site.

If the user enters their details into the text-box and clicks 'Submit', it does a POST to a controller that handles the log in.

If they make a mistake, such as entering an invalid email address, it will populate the ModelState with an error message and then redirect back to whatever page they were on before.

The problem is, because RenderAction occurs as a separate request, I'm losing the ViewModel.

Even when I put it into TempData it gets lost, since TempData is flushed on each separate request.

Is there a way of preserving data between consecutive Html.RenderAction calls?

If not, any suggestions on how I might be able to hack this? (Should put the data in Session?)


Here's what I've done for the time being. (This probably isn't the most ideal solution.)

I created a 'PreserveViewDataAttribute', which I put on any action for which I want to preserve the ViewData in the session.

In my BaseController, I overrode the 'Redirect' method with my own method, which does the following.

  1. Gets a reference to the Action method that called it (a bit of reflection here)

  2. Checks if this method has the 'PreserveViewDataAttribute' defined on it

  3. If it does, copies the current ViewData to a Session variable. (The label of the variable is the same as the current action name, with '_ViewData' tacked onto the end.)

  4. In either case, calls the base Redirect method.

Then I created a property in the BaseController called 'PreservedViewData', which returns the ViewData in session, relevant to the current action. (Or returns null if not found).

Thus, to preserve ViewData as long as I want, I need only decorate my action with 'PreserveViewDataAttribute', and then call 'PreservedViewData' whenever I need it.

Let me know if you want the source-code to this.


You might like this Post-Redirect-Get section's approach by Kazi Rashid.