Serialize MVC ViewDataDictionary - asp.net-mvc

I'm using SQL state server for session variables. I'm also storing ViewData in TempData so I can access the ModelState across a redirect. The problem is that the ViewDataDictionary is not serializable. Is there a way to hook into the session storage logic to serialize the ViewDataDictionary when the Session variable is stored?
Thanks.

I think you're breaking a fundamental idea of the MVC pattern.
You shouldn't need the session variable. You pass the model to the view, then the model is passed back to the controller. It doesn't matter if it's a redirect or not.

Instead of storing the whole ViewData dictionary in TempData, I just stored the values I needed. A bit hacky, but it'll work for now.

Related

Passing a model into RedirectToAction()

I'm curious how this works. In MVC you can call View() and pass a model as a parameter, but RedirectToAction (one of its incarnations at least) takes a 'routeValues' object, which appears to be the closest match.
If your model is passed in this parameter will that model type be available in the subsequent action method? Or are there caveats involved that might prevent accurate translation in some circumstances?
If you need to pass in some-what complex objects to an action after a redirect, you probably want to use either a Session or TempData:
From "What is ASP.NET MVC TempData"
ASP.NET MVC TempData dictionary is used to share data between
controller actions. The value of TempData persists until it is read or
until the current user’s session times out
By default TempData uses a Session to persist the information, however, as with much of MVC, this is an extensibility point, where you can plug in a Cookie-based provider if you prefer.
You cannot pass a model object in there but you can pass individual properties that will map to a model in the action that you redirect to.
That works by building up the url to redirect to using the properties, and the model binder in the receiving action.
Redirect... methods cause client-side-and-back trip, so - no, the model will not be available.
I think this is what you want :
Save your model in a Tempdata
RequestModel rq = new RequestModel()
....assign something to your model..
TempData["request"] = rq;
return Redirect("RequestAcknowledgement");
Now create an Action Result for the view you are redirecting to and pass your TempData back to a model. Then return the model to a view.
public ActionResult RequestAcknowledgement()
{
RequestsModel request = (RequestsModel)TempData["request"];
return View(request);
}

Persist data in MVC Razor without using TempData between requests

How do I can persist data in MVC Razor without using TempData between requests?
I see when we can use TempData from this, but don't want to TempData as it creates a state on the machine.
Thanks, Anish
EDIT: I want to persist the previous sort direction in a View page where a user is allowed to sort fields such as Name, Age etc.
FIX: I fixed it using ViewBag. Previous sort field/direction sent to View from Controller using ViewBag and then passed it back as query string in the next click.
Good FIX: I handled the everything in .js file such as checking and then in setting the previous sort field and previous sort dir in Controller.
This is what I finally did. I used ViewBag to send previous details to ViewPage and did the validation in a .js based on the current user action and passed it back to the controller in form-data.
Maintaining State in client page is something which is breaking the concept of HTTP which is stateless. Why do you want to maintain state ? If you are looking for some solution for Passing some data from your controller action to corresponding view, i would suggest you to go with a ViewModel where you fill the data for the dropdown and send that ViewModel object to the strongly typed view. You will have your data available there. Also you should grab data from your DataLayer ( from tables/ or Cache or etc..) in every request if you want some data.
You may pass a relevant id in the query string to get the corresponding data.
As RTigger mentioned, you may store some data in session. That will be available across all the pages till the life time of that session.
I haven't done a lot of ASP.NET MVC 3 recently, but I think the only real way you can persist data across requests is either with session state, cookies, or by posting data to the server every request.
ViewData, ViewBag, and TempData are all effectively killed at the end of each request, whereas session state, cookies, and post data is made available at the beginning of every request based on information from the client browser.
What particular scenario are you trying to persist data for?
You could pass those values as query string parameters when redirecting.
You can set parameters to hidden input fields if you post the form. But if you gonna call action by HTTPGET then you can pass values by using QueryString parameters.

ViewBag is NULL after RedirectToAction (+ reinitialization of ViewBag)

I have RedirectToAction as a return value in a controller and in my view I use ViewBag. While it's a well-known problem that ViewBag becomes empty after a RedirectToAction. I have a problem when I reinitialize ViewBag values in my overloaded controller in the OnActionExecuting method. ViewBag is empty again.
But the problem is that on my local PC (win7) it's working okay but on the web-hosting server (win 2008) it crashes. So can some one help saying what can cause that? Maybe it's a setting or something?
The ViewBag and ViewData only survives the current request. TempData is the thing to use when you use redirects (and only then): http://rachelappel.com/when-to-use-viewbag-viewdata-or-tempdata-in-asp.net-mvc-3-applications states this clearly:
[...] the TempData object works well in one basic scenario:
Passing data between the current and next HTTP requests
There was an exception deep inside data layer which was incorrectly captured and thereby prevented from propagation but caused ViewBag vanishing.
So be careful with exceptions catching.

Where to initialize TempData

I need a variable that will be used everywhere (controller, view, master page, ...). I was thinking of putting it in the TempData. Where is the best place to put an object there?
I thought of Page_Load but that's done after the controller.
I thought of the controller Initialize but the TempData seems to be cleared after that.
I couldn't use a session because the data could change on every request. I decided to initialize everything in the OnActionExecuting of the controller and it's working great.
You should use a Session variable rather than TempData. Variables stored in TempData will be destroyed after one request: Difference Between ViewData and TempData?
Here is a link documenting the various Client and Server side storage options in Asp.net
http://www.dotnetfunda.com/articles/article61.aspx

keep viewdata on RedirectToAction

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult CreateUser([Bind(Exclude = "Id")] User user)
{
...
db.SubmitChanges();
ViewData["info"] = "The account has been created.";
return RedirectToAction("Index", "Admin");
}
This doesnt keep the "info" text in the viewdata after the redirectToAction.
How would I get around this issue in the most elegant way?
My current idea is to put the stuff from the Index controlleraction in a [NonAction] and call that method from both the Index action and in the CreateUser action, but I have a feeling there must be a better way.
Thanks.
You can use TempData.
TempData["info"] = "The account has been created.".
TempData exists exactly for this situation. It uses Session as storage, but it will not be around after the second response.
From MSDN:
A typical use for a TempDataDictionary object is to pass data from an action method when it redirects to another action method. For example, an action method might store information about an error in the controller's TempData property (which returns a TempDataDictionary object) before it calls the RedirectToAction method. The next action method can then handle the error and render a view that displays an error message.
Use ViewData if your data should be accessible in View during "this" request. Use `TempData' if your data is for "next" request (for example POST-REDIRECT-GET design pattern).
If you need this more than once, a nice workaround would be creating ActionFilterAttributes which export/import the tempdata to viewdata and vice-versa. You can pass your ModelState in this way very nicely as well (demonstrated here - #13).
With a few adjustments to that piece of code you would have a clean solution, I think.
You could use the TempData controller property, but it has the disadvantage that it uses the session storage in the background. This means that you'll have extra work getting it to function on a web farm and you'll need to have sessions enabled in your application in the first place.
An alternative is to use cookies if you only need to transport a short message. This does require proper encryption of the cookie. Not relying on the TempData property also allows you to set messages in a non MVC context, for example in a classic ASHX page.
Take a look at FlashMessage which can save you some work implementing this yourself.
Since TempData appears to use storage, and any form of ITempDataProvider that is not "in-process", requires the object to be Serializable, TempData seems woefully inadequate in web farm situations... (ViewDataDictionary isn't itself serializable...) Does anyone have any suggestions for this?
The answer is TempData. The usage difference for clarification is as the following:
TempData = passing data from Action to another Action
ViewData = passing data from Action to a View

Resources