I have been trying to find out why submitting a form in my partialview makes some components of my model null. Just before calling the partialview, I have a model with count of AgainstWhoms and TimesPlaces each equal to one.

Even with a simplified partialview where only a column is added, on submitting to the controller, my AgainstWhoms and TimesPlaces collections are now null.

public class ComplaintViewModel
    {
        [Key]
        public int Id { get; set; }
.........
        public List<AgainstWhomViewModel> AgainstWhoms { get; set; }       
        public List<TimesPlacesViewModel> TimesPlaces { get; set; }        
        public List<WitnessesViewModel> Witnesses { get; set; }
    }

public async Task<ActionResult> GetNewComplaint(int intComplainantId)
        {
            var complaint = new ComplaintViewModel
            {
                ComplainantId = intComplainantId,
                StatusId = 1,
                ReceivedDate = DateTime.Now,
                AgainstWhoms = new List<AgainstWhomViewModel> { },
                TimesPlaces = new List<TimesPlacesViewModel> { },
                Witnesses = new List<WitnessesViewModel> { }
            };
            var newtime = new TimesPlacesViewModel { IncidentDate = DateTime.Today, IncidentLocation = "aaaaaaaaa" };
            complaint.TimesPlaces.Add(newtime);

            var complainee = new AgainstWhomViewModel { CountryId = 1, Email = "[email protected]"};
            complaint.AgainstWhoms.Add(complainee);

            ..................
            return PartialView("_ComplaintFormModal", complaint);
        }

Below is my simplified view.

@model ComplaintViewModel

<div>
  <form id="Complaintform" asp-controller="Complaint" asp-action="RegisterComplaint" method="post">
    <div class="form-row">
      <div class="form-group col-lg-8 required">
        <label asp-for="ComplaintTitle" class="control-label"></label>
        <input type="text" class="form-control" required asp-for="ComplaintTitle">
        <span asp-validation-for="ComplaintTitle" class="text-danger"></span>
      </div>
    </div>
    <button type="submit" value="Submit">Submit</button>
  </form>
</div>

In my controller post method, newComplaint.AgainstWhom and newComplaint.TimePlaces are now null, while other fields that do not belong to any of the linked lists are returned correctly:

    [HttpPost]
    public ActionResult RegisterComplaint(ComplaintViewModel newComplaint)
    {
      ..............
1

There are 1 best solutions below

1
Nan Yu On

You didn't render the TimesPlaces/AgainstWhoms so that data will lose since they are not in form collection .

If you want to edit the TimesPlaces/AgainstWhoms items , you can render like :

@for (int i = 0; i < Model.TimesPlaces.Count; i++)
{
    <tr>
        <td>
            @Html.TextBoxFor(model => model.TimesPlaces[i].IncidentDate)
        </td>
        <td>
            @Html.TextBoxFor(model => model.TimesPlaces[i].IncidentLocation)
        </td>

    </tr>
}

If you don't want to edit them , you can use hidden field :

@for (int i = 0; i < Model.TimesPlaces.Count; i++)
{

    @Html.HiddenFor(model => model.TimesPlaces[i].IncidentDate)
    @Html.HiddenFor(model => model.TimesPlaces[i].IncidentLocation)
}

But it's better to avoid that . If you don't want to edit them , i would prefer to query database with ID again for up-to-date records , and avoid posting large data in a request .