ASP.net MVC - How to persist model over various views

Adam Tolley picture Adam Tolley · Nov 5, 2009 · Viewed 8.5k times · Source

Situation: In some project management software written in asp.net I have a create project page (working fine). I need to add to this the ability to add tasks from a list of templates to this project pre-creation BUT the list of available tasks is dependent on some values sitting in the create form.

My abstract solution is this:

  • I have a "Create" view and an "Add Tasks" View - both strongly typed to a composite viewModel defined in the controller
  • My Create method checks which button was used to call it - if the button was "Add Tasks" it then renders the AddTasks view, passing the model in from the create view, again all in the same controller.
  • The AddTasks View posts to the Create view with one of two buttons, one loads the view and the other causes an actually DB save.

My Problem is this:

  • The different views use different properties of the same model, but in passing this model between them, the data is reset (in any case reload or save).
  • I am guessing this is happening from auto binding of data - though I thought fields not present on the form would not overwrite existing model data passed down.
  • There is hardly any code in the controller manipulating the model at present - It is only passed from view to view in these cases.

This is the controller code:

    // POST: /Project/Create/<viewModel>
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create([Bind(Exclude = "Id,id")] ProjectViewModel model)
    {
        if (model.SubmitValue == "Create")
        {
            try
            {
                model.Project.Id = Guid.NewGuid();
                model.Save(this.User.Identity.Name);
                return this.RedirectToAction("Details", new {id = model.Project.Id});
            }
            catch (Exception e)
            {
                this.ModelState.AddModelError(e.ToString(), e.ToString());
            }
            return View(model);
        }

        if(model.SubmitValue == "AddTasks")
        {
            return this.View("AddTasks",model);
        }

        return this.View(model);

    }


    //POST: /Project/AddTasks/ + model
    [Authorize, AcceptVerbs(HttpVerbs.Post)]
    public ActionResult AddTasks([Bind(Include = SelectedCarrierTasks")]ProjectViewModel model)
    {
        return View(model);
    }

The Question is: How do I maintain the state of the model across these views until it finally save it?

I would prefer to avoid any hackish (TempData) or JS dependant solutions, but I am not closed to these if they are really the best solution.

Thanks, Adam Tolley

Answer

Oleiro picture Oleiro · Nov 5, 2009

One simple solution is to persist the ViewModel object in a Session variable and bind the View from this source.I ts certainly not the most elegant solution. Another option, and probably less elegant one is persist this model data in the database, with some temporary/unsaved flag.