Sebastián Guzmán Sebastián Guzmán - 3 months ago 10
C# Question

MVC Post action is not getting any data from a List<t> object

I have problems to receive data from List, when seeing in Chrome it looks fine because has all values, but in Visual Studio Debug its not right, it fills list items, but not the values. What i'm doing wrong?

Model:

public class PermisoModel
{
public int Id;
public string Name;
public bool Checked;
}

public class ModuloModel
{
public int Id;
public string Name;
public List<PermisoModel> Permisos { get; set; }
}


Controller:

public ActionResult Permisos(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Usuario usuario = db.Usuario.FirstOrDefault(x => x.id_usuario == id && x.usu_estado == true);
if (usuario == null)
{
return HttpNotFound();
}
List<ModuloModel> ModuloModel = db.Modulo.Where(mod => mod.mod_estado == true).Select(mod => new ModuloModel {
Id = mod.id_modulo,
Name = mod.mod_nombre,
Permisos = db.Permiso.Where(per => per.id_modulo == mod.id_modulo && per.per_estado == true).Select(x => new PermisoModel { Id = x.id_permiso, Name = x.id_permiso + " - " + x.per_nombre, Checked = db.PermisoUsuario.Count(y => x.id_permiso == y.id_permiso && y.id_usuario == usuario.id_usuario)>0 }).ToList()
}
).ToList();
return View(ModuloModel);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Permisos(int? id, List<ModuloModel> model)
{

return View(model);
}


View:



@model List<ModuloModel>
@using Data.Models
@using (Html.BeginForm())
{
<p class="btn-group pull-right">
<a href="@Url.Action("Index")" class="btn btn-default">
<i class="glyphicon glyphicon-menu-left"></i>
Volver
</a>
<button type="submit" class="btn btn-warning"><i class="glyphicon glyphicon-pencil"></i> Editar</button>
</p>
<hr style="clear:both;" />
@Html.AntiForgeryToken()
for (int x = 0; x < Model.Count; x++)
{
<fieldset class="form-horizontal">
@Html.HiddenFor(model => model[x].Id)
<legend>@Model[x].Name</legend>
@for (int y = 0; y < Model[x].Permisos.Count; y++)
{
<div class="form-group">
<label>
@Html.HiddenFor(model => model[x].Permisos[y].Id)
@Html.CheckBoxFor(model => model[x].Permisos[y].Checked)
@Html.DisplayFor(model => model[x].Permisos[y].Name)
</label>
</div>
}
</fieldset>
}
}





Thanks in advance!

Answer

For model binder to map the posted form data to the parameter of your HttpPost action method, your viewmodel/dto classes properties should be public properties with set and get accessors

Your current code does not have set accessors. So model binder cannot set the values (from the posted form data) to it.

This should work.

public class PermisoModel
{
    public int Id { set; get; }
    public string Name { set; get; }
    public bool Checked { set; get; }
}

public class ModuloModel
{
    public int Id { set; get; }
    public List<PermisoModel> Permisos { get; set; }
}