Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC PRG pattern with children

I am trying to implement the PRG pattern by using the [ImportModelStateFromTempData] and [ExportModelStateToTempData] action filters. This pattern works great for flat models but I cannot get it to work when I have a child collection. My model looks like this:

public class QuestionModel
{
    public string QuestionText { get; set; }

    public ICollection<ChoiceModel> Choices { get; set; }
}

public class ChoiceModel
{
    public string ChoiceText { get; set; }
}

My controller is as follows:

[HttpGet, ImportModelStateFromTempData]
public ActionResult Create()
{
    return View();
}

[HttpPost, ExportModelStateToTempData]
public ActionResult Create(QuestionModel model)
{
     if(ModelState.IsValid)
     {
        // not getting here
     }

     return RedirectToAction("Create");
}

My view allows the user to add new items to the choices, and I have a validation that choices must be unique. When my ModelState is not valid, it will package up the ModelState into TempData and redirect to the HttpGet action.

At this point all of my child model values are in ModelState, but it does not reconstruct them when it passes the model to the view, therefore my view shows that there were 0 children added.

Is there a way to somehow merge the ModelState with the Model or can I not use this pattern with child objects?

like image 726
Dismissile Avatar asked Nov 12 '22 13:11

Dismissile


1 Answers

I doubt [ImportModelStateFromTempData] will reconstruct the model from ModelState, I imaging it just getting the user attempted values and validation errors, so as the model collection is not initialized at this point (GET) and you are not passing the collection from the POST, it will just render the model initial state, that's why it works well with flat models but not with collections like in this case.

So you must find a way to pass that collection or the hole model from POST to the GET Action, and the option is TempData.

//POST - if validation fails
TempData["model"] = model;

//GET - must check if TempData["model"] is null first
QuestionModel model = (QuestionModel)TempData["model"];
like image 154
JOBG Avatar answered Nov 15 '22 06:11

JOBG