Reputation: 377
I have this two lines in a Razor template:
@Html.Hidden("step", Model.Step)
<p>@Html.Label(Model.Step.ToString())</p>
And they produce two different values:
<input data-val="true"
data-val-number="The field Step must be a number."
data-val-required="The Step field is required."
id="step"
name="step"
type="hidden"
value="0">
<p>
<label for="">1
</label>
</p>
How is this possible?
Property Step
is of a type Int32
and is incremented every POST action.
EDIT:
@model ***.WebUI.Models.OrderViewModel
@{
ViewBag.Title = "New order";
}
<h2>
New order</h2>
@using (Html.BeginForm())
{
@Html.Hidden("step", Model.Step)
<p>@Html.Label(Model.Step.ToString())</p>
<div>
//other inputs
</div>
}
Upvotes: 3
Views: 279
Reputation:
You have not shown you POST method, but based on "Property Step is of a type Int32 and is incremented every POST action." I assume it looks something like
public ActionResult Edit(OrderViewModel model)
{
model.Step = model.Step + 1;
return View(model);
}
When you post a model, the models values are added to ModelState
(along with any ModelState errors) so in the first post, the ModelState
value of Step
will be 0
. Html helpers use ModelState
values for binding (if one exists) so when you return the view @Html.Hidden("step", Model.Step)
will bind to the value of 0
(not the models value of 1
). The reason for this behavior is explained in this answer.
The correct approach is to follow the PRG pattern (redirect to the GET method, passing a parameter indicating the Step
value and initialize a new OrderViewModel
), however you can make this work by clearing ModelState
so that the Html Helper will use the model value.
public ActionResult Edit(OrderViewModel model)
{
ModelState.Clear(); // clear all model state
model.Step = model.Step + 1;
return View();
}
However, use this with caution. ModelState.Clear()
removes all errors as well.
Upvotes: 2