0

So this is strange. I have a model composed of person and List<person>. when the user submits the view back to the controller, person is add to the List<person> and then we clear out all the person fields by the means of a person=new Person();.

I would expect that when return to the view, all the person fields are cleared out and the view is a "fresh" start. However, for some strage reason I cannot figure out, most of the fields for person are still filled out with the previous values (even after the person=new Person();).

The model is a complex model, composed of several "objects of objects", and some of the objects inherit from other objects. Still, I can't understand why the view still shows values from previous posts.

EDIT !!!!!

I am posting via a regular form post (HTML.BeginForm()). So here is my controller:

    [HttpPost]
    [ValidateAntiForgeryToken()]
    public ActionResult sendInscriptorRequest(inscriptionModel _model)
    {
        var _umbracoModel = Umbraco.TypedContentAtRoot().FirstOrDefault();
        _model = bllInscripcion.fillModel(_model);
        _model = _model.Map(_umbracoModel);
        if (_model.formAction == "addParticipants")
        {
            _model.participants.Add(_model.newParticipant);
            _model.newParticipant = new participantModel();
            _model.ui.participants.btnTotalParticipantsNumber += 1;
            return View("addParticipants", _model);
        }
        else
        {
            _model.newParticipant = bllInscripcion.preFillParticipantContactWithInscriptorContact(_model);
            return View("formularioInscripcion2", _model);
        }
    }
ekad
  • 14,436
  • 26
  • 44
  • 46
aplon
  • 445
  • 6
  • 24
  • It would help greatly to see your post-action code. – Eckert May 12 '15 at 14:13
  • Please show the controller code that does this – markpsmith May 12 '15 at 14:13
  • Also, how are you getting the data? Via an Ajax request? Standard form POST? – nik0lai May 12 '15 at 14:15
  • The last part of [this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111) explains the reason for this behavior. –  May 13 '15 at 00:07

2 Answers2

3

You trying to return the view with the model from the POST action method. That won't work because the intended behavior is to return the model state that was posted so the user can make corrections.

If you're posting data and then want to return an empty view you should redirect to the GET action method that returns the initial state of the view. It's known as a Post-Redirect-Get pattern.

http://en.wikipedia.org/wiki/Post/Redirect/Get

Following this pattern will also solve the problem of the user refreshing the page following the POST and getting that annoying dialog that says "You're about to resubmit data. Are you sure?" to which the user always responds "Yes" and then your system has to deal with the potential duplication.

Craig W.
  • 17,838
  • 6
  • 49
  • 82
  • THANK YOU VERY MUCH Craig and @mattytommo. I ended up using the PRG pattern. A BIG +1 for your answers and my eternal gratitude for your contributions (and sorry for my bad English). – aplon May 12 '15 at 15:06
2

Explanation of the problem:

This is because of ModelState. By default, MVC will retain the model state within a post action if you're returning the same view. To prevent this, simply clear it before returning the view:

ModelState.Clear();

This will mean that whatever model you pass back to the view will be used, not the one stored in model state.

DISCLAIMER:

You should use ModelState.Clear only when needed. Judging by your code, you don't need to use it. Simply redirecting to another page after you have performed the necessary logic is the better thing to do here (as per the PRG pattern).

Mathew Thompson
  • 55,877
  • 15
  • 127
  • 148
  • 2
    `ModelState.Clear()` is the nuclear option. I wouldn't recommend actually using that, since 99 times out of 100 people use it in scenarios where it shouldn't actually be used. Using `ModelState.Remove` to just remove the specific property is far preferable, but the best solution is simply to follow Post-Redirect-Get. – Chris Pratt May 12 '15 at 14:28
  • @ChrisPratt Agreed that PRG is the better solution, but there are scenarios in which `ModelState.Clear()` is useful (I'd say a lot more of out 1 in 100 :)) – Mathew Thompson May 12 '15 at 14:30
  • 1
    Considering I've never had to use it once in over 2 years of working with MVC, I'd say a lot less. – Chris Pratt May 12 '15 at 14:31
  • @ChrisPratt Well I've worked with MVC for around 5 years on enterprise level solutions (including major household name clients) and I'd say that it's more than that. – Mathew Thompson May 12 '15 at 14:32
  • Although it's legal code, it feels a bit like a hack. PRG pattern would be the standard design pattern to use here. – L-Four May 12 '15 at 14:35
  • @L-Three After we can now see the OP's code, you're right it's definitely a sledgehammer to crack a nut in this scenario. I've added the disclaimer, but left the explanation to help OP understand what's going on. – Mathew Thompson May 12 '15 at 14:38
  • Thanks for clarifying this in your answer! – L-Four May 12 '15 at 14:39
  • 1
    Well, no offense but big clients don't mean good code. It's not my intention to get into a flame war, but frankly clearing the `ModelState` completely is nothing short of a hack. I can't think of a single truly good use for it. Perhaps, you've encountered a scenario where it was absolutely necessary, but if so, it's a rare unicorn and certainly not worthy of actually *recommending* the approach. – Chris Pratt May 12 '15 at 14:39
  • @ChrisPratt Agreed, I don't want this to turn into the "my dad's bigger than your dad" argument. It's hacky: **yes**, it has it's uses: **rarely**. I have clarified my answer in that I don't want to *recommend* it, but merely *explain* the behaviour. – Mathew Thompson May 12 '15 at 14:41