Reputation: 2596
I am using MVC to display a simple form in a view:
ViewModel:
public class CreateSaleViewModel
{
public string OrderId { get; set; }
public decimal TotalAmount { get; set; }
public bool ShowInstoreConfirmDetails { get; set; }
}
Controller action:
[HttpGet]
public IActionResult CreateSale()
{
return View(new CreateSaleViewModel());
}
View:
@model CreateSaleViewModel
<form asp-controller="Sales" asp-action="CreateSale" method="post">
<input asp-for="OrderId" />
<input asp-for="TotalAmount" />
<button type="submit" name="CreateSale" id="CreateSale">
button
</button>
</form>
I then post to a new view, where the same details need to be entered. To do this I store the old values in hidden inputs and provide another form to re-enter the details.
ViewModel:
public class ConfirmDetailsViewModel
{
public string OrderId { get; set; }
public decimal TotalAmount { get; set; }
public string ConfirmOrderId { get; set; }
public decimal ConfirmTotalAmount { get; set; }
}
Controller:
[HttpPost("Confirmdetails")]
public IActionResult ConfirmDetails(CreateSaleViewModel model)
{
var viewModel = new ConfirmDetailsViewModel
{
ConfirmOrderId = model.OrderId,
ConfirmTotalAmount = model.TotalAmount,
OrderId = string.Empty,
TotalAmount = 0.0m
};
return View("ConfirmDetails", viewModel);
}
View:
@model ConfirmDetailsViewModel
<form asp-controller="Sales" asp-action="Summary" method="post">
<input type="hidden" value="@Model.ConfirmOrderId" id="OrderIdConfirm" />
<input type="hidden" value="@Model.ConfirmTotalAmount" id="TotalAmountConfirm" />
<input type="hidden" value="@Model.OrderId" id="banana" />
<input asp-for="OrderId" />
<input asp-for="TotalAmount" />
<button type="submit" name="CreateSale" id="CreateSale">
button
</button>
</form>
My problem is on the confirmdetails view orderId and TotalAmount retain the values that were posted from the previous page.
I have debugged the controller and can see the ConfirmOrderId and ConfirmTotalAmount properties have the correct values, and also OrderId and TotalAmount are empty strign and 0 respectively.
Even stranger is that
<input type="hidden" value="@Model.OrderId" id="banana" />
Has the correct value of "".
Does anyone know what is causing this issue?
Upvotes: 1
Views: 136
Reputation:
MVC stores the posted back values in ModelState.
These values are used by default in @Html helpers - as a convenience. This allows the values of hidden form fields to be preserved through postbacks, even if they don't have properties in the view-model.
Unfortunately what is usually a convenience turns into a headache, if you try to modify the model's properties within the action. Helpers take their values from ModelState, ignoring the updated view-model.
To solve this, call ModelState.Clear()
Controller:
[HttpPost]
public IActionResult ConfirmDetails(CreateSaleViewModel model)
{
var viewModel = new ConfirmDetailsViewModel
{
ConfirmOrderId = model.OrderId,
...
};
ModelState.Clear(); // force asp-helpers to use the updated model's values
return View("ConfirmDetails", viewModel);
}
Upvotes: 2