Best way to give Binding on objects from 1 to N - Asp.net MVC

Asked

Viewed 119 times

4

I would like to know how best to give the Binding of data in the object FuncaoGrupo of my Controller. Each item in the list Funcoes will generate 4 Checkbox in View.

I have the following class:

public class GrupoDeUsuario
{
    public GrupoDeUsuario()
    {
        Funcoes = new HashSet<FuncaoGrupo>();
    }

    [Key]
    public int GrupoDeUsuarioId { get; set; }

    [MaxLength(length: 100, ErrorMessage = "Descrição do grupo deve ser somente 100 caracteres")]
    [Required(ErrorMessage = "Descrição do Grupo de Usuário deve ser informada")]
    public string Descricao { get; set; }

    public ICollection<FuncaoGrupo> Funcoes { get; set; }

}

Note: I was able to do but using FormCollection, but I wonder if there’s a better or right way to do it.

2 answers

1

The best way is to move the user group back to the Action POST:

[HttpPost]
public ActionResult Salvar(GrupoDeUsuario grupoDeUsuario)
{
    /* Lógica de negócios aqui */
}

Possibly your problem of Binding is related to the fact that the ModelBinder does not send the values of each function linked to the user group back to the Controller. For that to happen, you need to have two things in your form:

  1. Each function record needs to be identified with an index;
  2. The fields of each function shall be indexed by the value contained in this index field.

In short, the index of a function is a <input type="hidden"> anywhere on the form whose name is Funcoes.index and value an integer or Guid. To simplify, I’ll use integers:

<input type="hidden" name="Funcoes.index" value="1" />

Now, the fields checkbox. You didn’t say their names, so I’ll call them Campo1, Campo2, Campo3, Campo4. Would look like this:

<input type="hidden" name="Funcoes.index" id="Funcoes_index" value="1" />
<input type="checkbox" name="Funcoes[1].Campo1" id="Funcoes_1_Campo1" value />
<input type="checkbox" name="Funcoes[1].Campo2" id="Funcoes_1_Campo2" value />
<input type="checkbox" name="Funcoes[1].Campo3" id="Funcoes_1_Campo3" value />
<input type="checkbox" name="Funcoes[1].Campo4" id="Funcoes_1_Campo4" value />

Just this is enough so that the Action recognize the values when submitting the form. Only this is a bit long to do, so it is better to use a tool for this. In which case, her name is Begincollectionitem. I’ve answered several times about her. What it does is generate this index field and index the fields for you, but it works well using Razor. It would look like this:

@foreach (var funcao in Model.Funcoes)
{
    using (Html.BeginCollectionItem("Funcoes"))
    {
        @Html.CheckBoxFor(_ => funcao.Campo1)
        @Html.CheckBoxFor(_ => funcao.Campo2)
        @Html.CheckBoxFor(_ => funcao.Campo3)
        @Html.CheckBoxFor(_ => funcao.Campo4)
    }
}

0

You can use Editorfor for your Functions collection without having to use Formcollection. You can do this with "for", with foreach will not work, already warning. Your View would be more or less like this:

@model SeuProjeto.GrupoDeUsuario

@Html.EditorFor(model => model.Descricao)

@for(int i = 0; i < model.Funcoes.Count; i++)
{
  @Html.EditorFor(model => model.Funcoes[i].DescricaoFuncao)
}

Your controller would look something like this:

public ActionResult Index()
{
   GrupoDeUsuario grupo = dbContext.GrupoDeUsuario.Include(g => g.Funcoes).FirstOrDefault();

   return View(grupo);
}

[HttpPost]
public ActionResult Index(GrupoDeUsuario grupo)
{
  // aqui voce tem o grupo, com suas funcoes preenchidas, sem usar form collection
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.