views:

60

answers:

2

I have an asp.net mvc app with a form.

When you submit the form, it adds records to the sql database with linq-to-sql. After adding the records, the controller displays the form again, and should show those new values on the form. But, when it displays the form, the values are blank, until you refresh the page.

While tracing through the code, I can see the records being added to the database when they are submitted, but the view doesnt display them, unless I refresh. The view is not the problem, it just displays the view model, which is missing the new records immediately after the post.

I know this is kind of vague, but wasnt sure what parts of code to include here.

Could this have something to do with data context life cycle? Basically, there is a data context created when the form is posted, then a different data context is created in the method that displays the form.

Any suggestions on what might be causing this?

Update:

There's a whole lot of code I could post here, but I'll try to give you a simplified version:

This code maintains a schedule of volunteer assignments

The view uses a view model with a list of schedules, and displays a form of schedules and their associated assignments. (child records)

When the form is posted, with a new schedule & assignemnts, a schedule record is created, and the related assignment records are created.

// Controller
public class SchedulerController : Controller
{
   ScheduleServices ScheduleSvc = new ScheduleServices();  // creates a new data context

   public ActionResult Index() 
   {
      return ShowSchedules();
   }

   [AcceptVerbs(HttpVerbs.Post)]
   public ActionResult Index(FormCollection form)
   {
       ScheduleSvc.ProcessRequest(form);
       return Index();
   }
}


public ActionResult ShowSchedules()
{
   SchedulerViewModel sched_vm = new SchedulerViewModel();
   sched_vm.EventsAndSchedules = ScheduleSvc.GetEventSchedulesFromDate();

   return View(sched_vm);
}


ProceessScheduleRequest(ScheduleRequest req)
{
   CreateSchedule(req);

   AssignmentServices AssignmentSvc = new AssignmentServices();  // creates it's own data context
   AssignmentSvc.Assign(req); 
}
A: 

After saving to the database, you should redirect to the controller method that displays the data. This will cause the controller method to look up the data from the database again, which will now display the newly-updated record.

Robert Harvey
Was already doing that. Just posted some simplified code.
PeteShack
Where is the code for ShowSchedules? I see what you're doing there with calling the controller methods directly. By doing that, you're not going through the routing engine; are there any ramifications (such as different route values in the HttpContext) that might be affecting you there?
Robert Harvey
In thinking about it more, I am of the mind that, instead of calling the controller methods directly from other controller methods, you should use `RedirectToRoute` or `RedirectToAction` so that the routing dictionaries are set up properly, and everything is done the same way, rather than two different ways.
Robert Harvey
A: 

I found the answer in this post (myth #10).

Apparentlly, using the same DataContext for multiple units of work, results in stale data, because objects tracked by a DataContext instance are not refreshed simply by requerying.

Instead of using the same DataCcontext for both adding the records, and then displaying the results, I used two separate ones and that fixed it. So instead of having one ScheduleServices instance for the whole controller class, I create one for the ProcessRequest() and a separate one for ShowSchedules().

PeteShack
You can avoid this problem by caching your data context on per-request basis. That's how I set up my entity repository and it works fine.
Adrian Grigore
Adrian, can you describe what you mean by "caching your data context on per-request basis?"
PeteShack