1

I'm passing structured data to my MVC page when it loads initially. After the user submits a contact form, I want to re-use the same data (I just "leave" the same page up) so I don't have to hit the database again. I declared a variable global to the controller to store the model data, but it's null at the end of the post back, so it looks like I can't re-use it there.

Seems like this would be a typical scenario. How do I handle it?

tereško
  • 58,060
  • 25
  • 98
  • 150
birdus
  • 7,062
  • 17
  • 59
  • 89

4 Answers4

4

If you are wanting to reuse viewmodel or other retrieved data that is not going to be part of the postback, you can either

a) Output it in hidden fields so that it is posted back to your action (meh) or

b) Store the object(s) in Session so that it will be available to any other controllers/actions in your application. If you are worried about memory, you could delete that session variable after you reuse it if you are not going to need to use it again.

On your initial page load, check if the session variable exists, if it does, you are good - else populate it.

Oh and why the global variable thing isn't working -> a controller is new'd up for each request (assuming using the default controller factory) and as such any global variables in the controller will be reset on each request.

Tommy
  • 39,592
  • 10
  • 90
  • 121
  • +1 for storing it in hidden fields. I don't love the idea of storing all that data in a session object. – Chase Florell Jan 19 '12 at 20:01
  • add to b) that you can use `TempData` which will delete the data after being read. – gdoron Jan 19 '12 at 20:04
  • Okay. So there's no magic happening. That's good to know. I think the Session object is a good way to go for me. The object I need to store isn't all that big. Thanks! – birdus Jan 19 '12 at 22:32
4
public ActionResult Foo()
{
    var model = GetModelFromDB();
    Return View(model);
}

[HttpPost]
public ActionResult Foo(Entity model)
{
    Return View(model);
}

Asp.net-mvc is stateless so each HTTP request has a different context, and each time you hit the controller all it's data reset in the constructor, this why you get null.

You can get the model in the post if it's properties are within the submitted form .

gdoron
  • 147,333
  • 58
  • 291
  • 367
  • 1
    +1. Also, As @Tommy said above, you can store the fields that aren't technically part of the View in a hidden field. Then when you post the data back to the controller, the hidden data is contained in the post, and the ModelBinder will rebuild the model and reuse it on it's next response. – Chase Florell Jan 19 '12 at 20:03
0

If you really don't want to leave the page you are on, and don't want to post all the other data back as KMan suggests, but still want to capture the users contact information/data you could post the contact info using ajax.

K. Bob
  • 2,668
  • 1
  • 18
  • 16
  • 1
    one should probably do a combination of both. If a user doesn't have Javascript enabled, you don't want to throw them a `null` object. – Chase Florell Jan 19 '12 at 20:44
  • I would probably not do both but accept that I have to make a trip to the database to repopulate the view in the event a user doesn't have javascript but it's a fair point worth considering. – K. Bob Jan 19 '12 at 21:11
-1

If you have your view model as an argument to your method, you can just return it to the view on postback. Ex:

public ActionResult TestAction(MyViewModelType testViewModel)
{
   //Do logic

    return View("view",testViewModel);

}

Note that you have to have the data inside the form you are posting.

Per Kastman
  • 4,466
  • 24
  • 21