Raman verma
Raman verma

Reputation: 73

LIST<VIEWMODEL> in view object is returning null in controller mvc.net

I have a list of class object and which is bind with view like this

@model List<Rep.Models.ContactReportSettingViewModel>
var accountArr = Model.Select(x => new { x.AccountId, x.CarrierId, x.AccountNumber, x.CarrierName, x.ClientId, x.ContactId }).Distinct();

I have a loop here on var object

@foreach (var accountRow in accountArr)
{
  @Html.LabelFor(x => accountRow.AccountNumber, accountRow.AccountNumber, new { @id = accountRow.AccountId })              

but when I click on save it is returning null or values or not set with the class properties I am accessing this in controller like this:

public RESULT method(List<ContactReportSettingViewModel> model)
{ 
  model is null here
  // return View(model);            
}

But in model I am getting null. What I am doing wrong?

When I use this

public RESULT method(ContactReportSettingViewModel model)
{ 
  // return View(model);            
}

Then in model object I can see all the properties but values does not set to those properties

Upvotes: 2

Views: 4098

Answers (2)

user3559349
user3559349

Reputation:

You cannot use a foreach loop to generate form controls for a collection because your generating duplicate name attributes that have no relationship to your model (and duplicate id attributes which is invalid html). You can use either a for loop in the view, or use an EditorTemplate for your model.

Note you need to remove your Linq .Select() code and do the filtering in the controllers GET method.

Using a for loop in the main view (note the model must be IList<T>)

@model List<Rep.Models.ContactReportSettingViewModel>
@using (Html.BeginForm())
{
  @for (int i = 0; i < Model.Count; i++)
  {
    @Html.LabelFor(m => m[i].AccountNumber)
    @Html.TextBoxFor(m => m[i].AccountNumber)
    @Html.ValidationMessageFor(m => m[i].AccountNumber)
    .....
  }
  <input type="submit" .../>
}

Using an EditorTemplate. Create a partial view in /Views/Shared/EditorTemplates/ContactReportSettingViewModel.cshtml (note the name of the file must match the model class name)

@model Rep.Models.ContactReportSettingViewModel

@Html.LabelFor(m => m.AccountNumber)
@Html.TextBoxFor(m => m.AccountNumber)
@Html.ValidationMessageFor(m => m.AccountNumber)
  .....

and then in the main view (note the model can be IEnumerable<T>)

@model IEnumerable<Rep.Models.ContactReportSettingViewModel>
@using (Html.BeginForm())
{
  @Html.EditorFor(m => m)
  <input type="submit" .../>
}

In both cases the generated html will include the correct name attributes with indexers which will be bound to your model in the POST method

<input type="text" name="[0].AccountNumber" .. />
<input type="text" name="[1].AccountNumber" .. />

Upvotes: 2

Lali
Lali

Reputation: 2866

Follow the following checklist

1) Make sure you added thing binding statement on top of your view

@model List<ClassName>

2) Then check your is being submitted to the function your mentioned in question and also check the parameter type is same as you mentioned while binding the page.

if you are using html table type structure to display list items then you also need to bind your list with each row. like for Cell[0][0] bind yourList[0].EmployeeId, Cell[0][1] bind yourList[0].EmployeeName and so on for all the column and then rows by using loop.

Upvotes: 0

Related Questions