0

I am trying to post model with several hidden fields (basically saving user input).

Model for this view:

public class LoanModel
{
    public LoanCalendarDTO LoanCalendar { get; set; }
    public EnterLoanParams LoanParams { get; set; }
}

Model that I try to post back:

public class EnterLoanParams
{
    [Required]
    [DataType(DataType.Currency)]
    public double TotalLoanAmount { get; set; }

    [Required]
    [RegularExpression(@"([0-9]{0,2}(,{0,1}([0-9]{0,2})))", ErrorMessage = "Please enter in format as xx,xx")]
    public string Rate { get; set; }

    [Required]
    [RegularExpression(@"([0-9]{0,2})", ErrorMessage = "2 digits ")]
    public int YearsToPay { get; set; }

    [Required] [DataType(DataType.Date)] public DateTime Start { get; set; }
    public List<DecreaseModel> Decreases { get; set; } = new List<DecreaseModel>();
}

And DecreaseModel is:

public class DecreaseModel
{
    [Required] 
    public string DecreaseType { get; set; }

    [Required] 
    public double Amount { get; set; }

    [Required] 
    public DateTime? Start { get; set; }

    public DateTime? End { get; set; }
    public Guid ID { get; set; }

    public DecreaseModel()
    {
        ID = Guid.NewGuid();
    }
}

In view I display them as:

@model Front.Models.LoanModel

@{
    ViewBag.Title = "title";
    Layout = "_Layout";
}
<form method="post" asp-controller="Home" id="form">
    <input class="form-control" name="TotalLoanAmount" type="number" asp-for="LoanParams.TotalLoanAmount" hidden/>
    <input class="form-control" name="Rate" type="text" asp-for="LoanParams.Rate" hidden/>
    <input class="form-control"  name="YearsToPay" type="text" asp-for="LoanParams.YearsToPay" hidden/>
    <input class="form-control" name="Start" type="date" asp-for="LoanParams.Start" hidden/>

    @for (int index = 0; index < Model.LoanParams.Decreases.Count; index++)
          {
              @Html.HiddenFor(m => @Model.LoanParams.Decreases[index].Amount)
              @Html.HiddenFor(m => @Model.LoanParams.Decreases[index].Start)
              @Html.HiddenFor(m => @Model.LoanParams.Decreases[index].End)
              @Html.HiddenFor(m => @Model.LoanParams.Decreases[index].DecreaseType)
              @Html.HiddenFor(m => @Model.LoanParams.Decreases[index].ID)
          }

    <button class="btn col-12 btn-success align-content-center btn-lg"
            asp-action="Index" asp-controller="Home" type="submit">Return Back</button>
</form>

I can see that hidden fields are populated with correct values in browser debugger:

populated fields

Post action:

[HttpPost]
public IActionResult Index(EnterLoanParams loan)
{
    return View(loan);
}

But on post I receive empty List:

empty list

related links: Asp.net mvc view with Ienumerable model returns null on submit

Assign IENumerable<int> to a hiddenfor

EDIT: working code for view:

 @for (int index = 0; index < Model.LoanParams.Decreases.Count; index++)
          {
              <input class="form-control" name="Decreases[@index].Amount" type="number"
                     asp-for="LoanParams.Decreases[index].Amount" hidden/>
              <input class="form-control" name="Decreases[@index].DecreaseType" type="text" 
                     asp-for="LoanParams.Decreases[index].DecreaseType" hidden/>
              <input class="form-control" name="Decreases[@index].Start" type="date" 
                     asp-for="LoanParams.Decreases[index].Start" hidden/>
              <input class="form-control" name="Decreases[@index].End" type="date" 
                     asp-for="LoanParams.Decreases[index].End" hidden/>
              <input class="form-control" name="Decreases[@index].ID" 
                     asp-for="LoanParams.Decreases[index].ID" hidden/>           
          }
Michael Snytko
  • 327
  • 3
  • 13

1 Answers1

1

The name attributes of the hidden fields for Decreases have the LoanParams. prefix, which means that they will be looking to bind to a model with the name of LoanParams.

You need to make the name Decreases[index].{Prop} (as you have done with the other hidden fields). You can do it like <input type='hidden' name='Decreases[index].{Prop}' value='your-value'>

MultiValidation
  • 823
  • 7
  • 21