Best way to bind objects from 1 to N - asp.net MVC

4

I'd like to know how to best give the Binding of data in object FuncaoGrupo of my Controller . Each item in the Funcoes list will generate 4 Checkbox in the 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 was using FormCollection , but I would like to know if there is a better or correct way to do this.

    
asked by anonymous 17.11.2015 / 02:39

2 answers

1

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

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

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

  • Each role record must be identified with an index;
  • The fields of each function should be indexed by the value contained in this index field.
  • In summary, 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 . For simplicity, I'll use integers:

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

    Now, the checkbox fields. You did not say their names, so I'll call them Campo1 , Campo2 , Campo3 , Campo4 . It 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 />
    

    This alone is enough for Action to recognize the values when submitting the form. It's just a bit of a long story, so it's better to use a tool for it. In this case, her name is BeginCollectionItem . I have answered it over and over again . What it does is generate this index field and index the fields for you, but it works fine 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)
        }
    }
    
        
    21.11.2015 / 06:34
    0

    You can use an EditorFor for your Funcoes collection, without having to use the FormCollection. You can do this with "for", with foreach not working, I warn you. Your View would look something 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
    }
    
        
    20.11.2015 / 23:55