1

I've got a form that submits a model. The controller saves that model to the database, then creates a new model and returns an EditCreate view with that new model.

The problem I'm having is that the new model isn't being displayed. Instead the model that was just posted is shown. I follow it through the debugger to the view and see the values are new, but when the page displays, it shows all the old values that were just submitted.

Controller

[HttpPost]
public ActionResult AddProduct(MyEntityModel myModel)
{
    // Save
    if (myModel.ID != 0) {
        Update(myModel);
    } else {
        Add(myModel);
    }

    ModelState.Clear(); // This fixed it

    // Show page for new model
    MyEntityModel newModel = new MyEntityModel();
    newModel.ID = 0;

    // Edit/Create page
    ActionResult ret = EditCreateRow(newModel);

    return ret;
}

Model

public partial class STM_AuditData
{
    public int ID { get; set; }
    public Nullable<System.DateTime> ServiceDate { get; set; }
    public string Product { get; set; }
}

View

@Html.LabelFor(model => model.ServiceDate)
@Html.EditorFor(model => model.ServiceDate)
@Html.LabelFor(model => model.Product)
@Html.EditorFor(model => model.Product)
@Html.HiddenFor(model => model.AuditID)

What can I do to ensure the correct model shows? Thanks.

Here's the code for EditCreateRow

public ActionResult EditCreateRow(MyEntityModel row)
{
    MyEntityModel.IntsToBools(ref row);

    EditCreate_SetViewBagItems(row);

    return View("~/Views/MyEntityModel/EditCreate.cshtml", row);
}
Jooooosh
  • 331
  • 2
  • 4
  • 13
  • 1
    There is no clue in the code you've posted that I can see. Is it possible that a different controller method is being called? – Slappywag Dec 16 '14 at 13:40
  • 1
    can you post the code for `EditCreateRow` method? That is what creates the action result. Also, you want to display a new model, instead of the saved, right? – Guillermo Gutiérrez Dec 16 '14 at 13:55
  • K the code's in there. EditCreate_SetViewBagItems is kind of messy, but it doesn't touch the model. I'm working with an existing database, and EditorFor won't let me set some properties as checkboxes when they should be, so IntsToBools moves those values to temporary properties in the model. – Jooooosh Dec 16 '14 at 14:11
  • Is anything different when you use `RedirectToAction` in your `AddProduct` to redirect it to the `EditCreateRow` method, or is it the same problem? – Corey Adler Dec 16 '14 at 14:22
  • I copied the code in there just now, and the same thing happened. Could it have something to do with the ModelState or something similar? – Jooooosh Dec 16 '14 at 14:24
  • I know it sounds basic, but have you stepped through your code with the debugger? The most obvious mistake here would be that this controller method isn't being called, and another one is being called instead (Perhaps an overload of AddProduct?). – Slappywag Dec 16 '14 at 14:25
  • Yeah to the view. All the values are correct even in the view, but when the page loads in the browser it's the old model's values. – Jooooosh Dec 16 '14 at 14:27
  • So you step through the view and it seems to be generating the correct values, but then the browser loads with old values? Perhaps your browser is displaying a cached page or something as daft as that? – Slappywag Dec 16 '14 at 14:31
  • I have no idea. Do you think deleting the cache and cookies will help? – Jooooosh Dec 16 '14 at 14:32
  • Worth a try if you're banging your head against a brick wall! – Slappywag Dec 16 '14 at 14:33
  • @Mate I want to show newModel, not myModel. – Jooooosh Dec 16 '14 at 14:37
  • @ChrisRedhead I deleted the cache and history, but it didn't work. I tried it on firefox too and the same thing happened. – Jooooosh Dec 16 '14 at 14:42

1 Answers1

5

The reason this is the case, is how the HtmlHelper works. When setting the value in the HTML-element, it has several options to get the value, using implementations of IValueProvider. You can check the default list at the aspnetwebstack. Compared to the better MVC frameworks out there, ASP.NET MVC is counter-intuitive.

If you add

ModelState.Clear()

before returning, I think you might have it solved.

Jeroen
  • 91
  • 1
  • Oh my balls it worked. I've been banging my head against a wall because of this for too long. Thanks! – Jooooosh Dec 16 '14 at 14:45
  • Is there another web MVC framework you'd suggest using? – Jooooosh Dec 16 '14 at 15:02
  • [FubuMVC](http://mvc.fubu-project.org/), [Nancy](http://nancyfx.org/) are a two good ones. Another one is [openrasta](https://github.com/openrasta/openrasta/wiki), but I personally never used it. – Jeroen Dec 16 '14 at 15:18
  • Interesting, and counter-intuitive as you say. Another way to avoid this would be to use the [Post-Redirect-Get pattern](http://en.wikipedia.org/wiki/Post/Redirect/Get). This way, the old model state is lost on the redirect, and this also help to avoid duplicate data submissions. – Guillermo Gutiérrez Dec 16 '14 at 15:42
  • This behavior is by default and the reason for it is explained [in this answer](http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from-code/26664111#26664111). The correct approach is to redirect to a GET method –  Dec 16 '14 at 21:10