This question is a bit different than most. My code works but I don’t understand why it works.
I am trying to understand why changes made in the form get persisted after posting to the server.
Model:
public class TestUpdateModel
{
public int Id { get; set; }
public List<CarrierPrice> Prices { get; set; }
public TestUpdateModel() { } // parameterless constructor for the modelbinder
public TestUpdateModel(int id)
{
Id = id;
Prices = new List<CarrierPrice>();
using (ProjectDb db = new ProjectDb())
{
var carriers = (from c in db.Carriers
select c);
foreach (var item in carriers)
{
var thesePrices = item.Prices.Where(x => x.Parent.ParentId == Id);
if (thesePrices.Count() <= 0)
{
Prices.Add(new CarrierPrice
{
Carrier = item
});
}
else
Prices.Add(thesePrices.OrderByDescending(x => x.DateCreated).First());
}
}
}
}
Controller:
public ViewResult Test(int id = 1)
{
TestUpdateModel model = new TestUpdateModel(id);
return View(model);
}
[HttpPost]
public ViewResult Test(TestUpdateModel model)
{
model = new TestUpdateModel(model.Id);
return View(model); // when model is sent back to view, it keeps the posted changes... why?
}
View
@model Namespace.TestUpdateModel
@{ ViewBag.Title = "Test"; }
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
@Html.HiddenFor(model => model.Id)
@Html.EditorFor(x => x.Prices)
<input type="submit" value="Save" />
}
EditorTemplate
@model Namespace.CarrierPrice
<tr>
<th>
@Html.HiddenFor(model => model.CarrierPriceId)
@Html.HiddenFor(model => model.DateCreated)
@Model.Carrier.Name
</th>
<td>
$@Html.TextBoxFor(model => model.Fee)
</td>
</tr>
The Source of My Confusion
1) Load the page in the browser
2) Change the value of the model.fee TextBox
3) Submit
At this point I would expect that model = new TestUpdateModel(model.Id); would create a new TestUpdateModel object and wipe out my changes so the original values re-appear when the view is returned. But what actually happens is my changes in the form are persisted to the postback.
Why does this happen?
Thanks for any help.
No. The reason is that the View Engine looks in the ModelState to fill your values before it looks at the model when it renders your view. If there are posted values, then it will find those first and use them.
If you want to override this behavior, then you need to clear the ModelState first with: