Search code examples
c#razorhtml-helper

wrong value in hidden input Razor c#


I have model property int? CaseId

public class TaskDetailsVm
{
    public TaskDetailsVm(Task task)
    {
        CaseId = task.CaseID;
    }

    public int? CaseId { get; set; }
}

and on view:

@Html.HiddenFor(x => x.CaseId) => 0
@Html.Hidden("CaseId", Model.CaseId) => 0
@Html.Hidden("qwe", Model.CaseId) => real value
<input type="hidden" id="CaseId" name="CaseId" value="@Model.CaseId" /> => real value

in browser I see this:

<input data-val="true" data-val-number="The field CaseId must be a number." id="CaseId" name="CaseId" type="hidden" value="0">
<input id="CaseId" name="CaseId" type="hidden" value="0">
<input id="qwe" name="qwe" type="hidden" value="22906">
<input type="hidden" id="CaseId" name="CaseId" value="22906">

Why can I see the following? I don't see any scripts to override this value. And how can I resolve it? Also for first line of code I see additional attributes data-val="true" and data-val-number="The field CaseId must be a number." for some reasons that I can't understand.


Solution

  • This has to do with the ModelState. As per this article:

    ASP.NET MVC assumes that if you’re rendering a View in response to an HTTP POST, and you’re using the Html Helpers, then you are most likely to be re-displaying a form that has failed validation. Therefore, the Html Helpers actually check in ModelState for the value to display in a field before they look in the Model. This enables them to redisplay erroneous data that was entered by the user, and a matching error message if needed. Since our [HttpPost] overload of Index relies on Model Binding to parse the POST data, ModelState has automatically been populated with the values of the fields. In our action we change the Model data (not the ModelState), but the Html Helpers (i.e. Html.Hidden and Html.TextBox) check ModelState first… and so display the values that were received by the action, not those we modified.

    Now in this case: @Html.HiddenFor(x => x.CaseId, new {Value = @Model.CaseId}), since you are explicitly defining a value for the current Model, it displays the value that you expect. You can use ModelState.Clear(); in your Controller after your POST on the form to reset the model values.