MVC 3 - Html.EditorFor seems to cache old values after $.ajax call

awrigley picture awrigley · Sep 14, 2011 · Viewed 18.7k times · Source

This is a follow on from the following question:

MVC 3 + $.ajax - response seems to be caching output from partial view

There is a detailed description of the problem over there. However, I have now managed to narrow down the problem, that seems to be with the Html.EditorFor helpers, hence the new question.

The issue:

I post data to the server using $.ajax, then return the html of the partial view that holds the input controls. The problem is that, despite passing a newly created object to the Partial Views model, the various @Html.EditorFor and @Html.DropDownListFor helpers return the OLD DATA!.

I can prove that the model has correctly passed in a new object to the helpers, by printing the value out beside the Html helper. Ie:

@Html.EditorFor(model => model.Transaction.TransactionDate) 
@Model.Transaction.TransactionDate.ToString()

As the following image shows, the @Html.EditorFor is returning the wrong data:

Cached response...

[Note that the value beside the Comentario text box is a date time, because I was testing replacing the default values with a value that would change with each post, ie, a DateTime.]

If I replace the @Html.EditorFor for TransactionDate with a plain old @Html.TextBox():

@Html.TextBox("Transaction_TransactionDate", Model.Transaction.TransactionDate)

Then it renders the correct TransactionDate value for a new Transaction object, ie, DateTime.MinValue (01/01/0001...).

Therefore...

The problem is with the @Html.EditorFor helpers. The problem also happens with TextBoxFor and DropDownListFor.

The problem being that these helpers seem to cache the old value.

What am I doing wrong??!

EDIT:

I have just tried debugging in the custom Editor template for dates, and in there, ViewData.TemplateInfo.FormattedModelValue shows the correct value, ie, "01/01/0001". However, once it gets to Fiddler, the response is showing the old date, eg, "01/09/2011" in the image above.

As a result, I just think that there is some caching going on here, but I have none set up, so nothing makes any sense.

Answer

Darin Dimitrov picture Darin Dimitrov · Sep 16, 2011

There is no caching involved here. It's just how HTML helper work. They first look at the ModelState when binding their values and then in the model. So if you intend to modify any of the POSTed values inside your controller action make sure you remove them from the model state first:

[HttpPost]
public virtual ActionResult AjaxCreate(Transaction transaction)
{
    if (ModelState.IsValid)
    {
        service.InsertOrUpdate(transaction);
        service.Save();
    }
    service.ChosenCostCentreId = transaction.IdCostCentre;
    TransactionViewModel viewModel = new TransactionViewModel();
    ModelState.Remove("Transaction");
    viewModel.Transaction = new Transaction();
    ModelState.Remove("CostCentre");
    viewModel.CostCentre = service.ChosenCostCentre;
    ...

    return PartialView("_Create", viewModel);
}