Answered by:
Hidden form values not binding on Form POST

Question
-
User-1091461227 posted
I am sending a List to the view. Trying to submit each item in the list through a form.
Model:
public partial class Model { public int Id { get; set; } public string UId { get; set; } public int WId { get; set; } public bool IsEnabled { get; set; } public virtual AspNetUsers User { get; set; } public virtual WModel W { get; set; } }
Controller:
public IActionResult UWC() { List<Model> uW = db.UW.Include(x => x.U).Include(x=>x.W).ToList(); return View(uW); } [HttpPost] public IActionResult UWC(Model uW) { var s = ModelState.ErrorCount; return RedirectToAction("UWC"); }
View
@model List<Model> <table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model[0].W.Name) </th> <th> @Html.DisplayNameFor(model => model[0].W.Type) </th> <th> @Html.DisplayNameFor(model => model[0].W.Description) </th> <th> @Html.DisplayNameFor(model => model[0].W.IsActive) </th> </tr> </thead> <tbody> @for (var item = 0; item < Model.Count(); item++) { <tr> <td> @Html.DisplayFor(model => model[item].W.Name) </td> <td> @Html.DisplayFor(model => model[item].W.Type) </td> <td> @Html.DisplayFor(model => model[item].W.Description) </td> <td> @if (Model[item].IsEnabled) { @try { <form asp-action="UWC" asp-controller="UM" method="post"> <div class="switch switch--horizontal switch--no-label "> <input asp-for="@Model[item].IsEnabled" type="radio" value="@Model[item].IsEnabled" class="form-control" /> <input asp-for="@Model[item].IsEnabled" type="radio" value="false" class="form-control" /> <span class="toggle-outside"><span class="toggle-inside"></span></span> </div> <input type="hidden" asp-for="@Model[item].Id" value="@Model[item].Id" /> <input type="hidden" asp-for="@Model[item].WId" value="@Model[item].WId" /> <input type="hidden" asp-for="@Model[item].UId" value="@Model[item].UId" /> </form> } catch (Exception e) { var s = e.Message; } } </td> </tr> } </tbody> </table> </div> </div> </div> @section Scripts{ <script> $(function () { $('input[type=radio]').change(function () { $(this).closest('form').submit(); }); }); </script> }
The above is the complete code.
When I submit the form using radio button toggle, only the IsEnabled property is getting bound on POST.
But the page source shows that all the properties are being properly bound in the view i.e Id,Uid,Wid all these properties have been replaced by their values.
@Model[item].Id is not necessarily in sequence, but I believe item - the loop variable determines model binding.
When the Page source has the model values, why is it not being reflected on POST?
If model binding is breaking, how come the IsEnabled property is being bound correctly?Monday, September 9, 2019 7:54 PM
Answers
-
User711641945 posted
Hi itsmeabhilashgk,
When you pass the value to the action,your asp-for specifies a value instead of the property in the model(You could press F12 in the frontend). You need to add a 'name' tag to specify its name.Here is a simple workaround:
<table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model[0].W.Name) </th> <th> @Html.DisplayNameFor(model => model[0].W.Type) </th> <th> @Html.DisplayNameFor(model => model[0].W.Description) </th> <th> @Html.DisplayNameFor(model => model[0].W.IsActive) </th> </tr> </thead> <tbody> @for (var item = 0; item < Model.Count(); item++) { <tr> <td> @Html.DisplayFor(model => model[item].W.Name) </td> <td> @Html.DisplayFor(model => model[item].W.Type) </td> <td> @Html.DisplayFor(model => model[item].W.Description) </td> <td> @if (Model[item].IsEnabled) { @try { <form asp-action="UWC" asp-controller="UM" method="post"> <input type="hidden" asp-for="@Model[item].Id" name="Id" value="@Model[item].Id" /> <input type="hidden" asp-for="@Model[item].WId" name="WId" value="@Model[item].WId" /> <input type="hidden" asp-for="@Model[item].UId" name="UId" value="@Model[item].UId" /> <div class="switch switch--horizontal switch--no-label "> <input asp-for="@Model[item].IsEnabled" type="radio" name="IsEnabled" value="@Model[item].IsEnabled" class="form-control" /> <input asp-for="@Model[item].IsEnabled" type="radio" name="IsEnabled" value="false" class="form-control" /> <span class="toggle-outside"><span class="toggle-inside"></span></span> </div> </form> } catch (Exception e) { var s = e.Message; } } </td> </tr> } </tbody> </table>
>>If model binding is breaking, how come the IsEnabled property is being bound correctly?
Actually,the model binding is not successfull.The reason for why the value of IsEnabled is false is that the default value of bool property is false(like the default value of string is null).
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, September 10, 2019 6:42 AM
All replies
-
User475983607 posted
The action is expecting a single input parameter type. The View markup is configured as a collection. I recommend changing the View markup names to match the action input. change the for to a foreach. I suppose you could try changing the action input to an array but I think only the first record will bind correctly.
Monday, September 9, 2019 8:17 PM -
User-1091461227 posted
But, I am using a form Inside a loop and posting each individual item in the list. Each item is bound to a seperate event trigger of its own. Also one of the values in the form is binding, if model binding is failing shouldn't I recieve null in the action?Monday, September 9, 2019 8:30 PM -
User475983607 posted
itsmeabhilashgk
But, I am using a form Inside a loop and posting each individual item in the list. Each item is bound to a seperate event trigger of its own. Also one of the values in the form is binding, if model binding is failing shouldn't I recieve null in the action?Your markup is designed to look like a collection but the action input is designed to accept a single type. Why not just follow standard patterns and design the form as a single item since that what you are doing anyway. Simply replace the for with a foreach.
Monday, September 9, 2019 11:06 PM -
User711641945 posted
Hi itsmeabhilashgk,
When you pass the value to the action,your asp-for specifies a value instead of the property in the model(You could press F12 in the frontend). You need to add a 'name' tag to specify its name.Here is a simple workaround:
<table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model[0].W.Name) </th> <th> @Html.DisplayNameFor(model => model[0].W.Type) </th> <th> @Html.DisplayNameFor(model => model[0].W.Description) </th> <th> @Html.DisplayNameFor(model => model[0].W.IsActive) </th> </tr> </thead> <tbody> @for (var item = 0; item < Model.Count(); item++) { <tr> <td> @Html.DisplayFor(model => model[item].W.Name) </td> <td> @Html.DisplayFor(model => model[item].W.Type) </td> <td> @Html.DisplayFor(model => model[item].W.Description) </td> <td> @if (Model[item].IsEnabled) { @try { <form asp-action="UWC" asp-controller="UM" method="post"> <input type="hidden" asp-for="@Model[item].Id" name="Id" value="@Model[item].Id" /> <input type="hidden" asp-for="@Model[item].WId" name="WId" value="@Model[item].WId" /> <input type="hidden" asp-for="@Model[item].UId" name="UId" value="@Model[item].UId" /> <div class="switch switch--horizontal switch--no-label "> <input asp-for="@Model[item].IsEnabled" type="radio" name="IsEnabled" value="@Model[item].IsEnabled" class="form-control" /> <input asp-for="@Model[item].IsEnabled" type="radio" name="IsEnabled" value="false" class="form-control" /> <span class="toggle-outside"><span class="toggle-inside"></span></span> </div> </form> } catch (Exception e) { var s = e.Message; } } </td> </tr> } </tbody> </table>
>>If model binding is breaking, how come the IsEnabled property is being bound correctly?
Actually,the model binding is not successfull.The reason for why the value of IsEnabled is false is that the default value of bool property is false(like the default value of string is null).
Best Regards,
Rena
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, September 10, 2019 6:42 AM -
User-1091461227 posted
Hi, the above works perfectly, thank you :)
However now facing the following:
https://stackoverflow.com/questions/57873242/net-core-radio-button-always-returns-false
Any leads as to why? :)Tuesday, September 10, 2019 2:47 PM