Error saving a relationship Many-To-Many [closed]

2

Following the templates this question , I'm having problems trying to save the data (keys of each of the records) in the table created to make the data relationship. Here's the post method I built:

Controller

[HttpPost, ValidateAntiForgeryToken]
    public ActionResult Novo(UsuariosNovo form, NivelCheckbox checkbox)
    {
        var usr = new Usuario();

        foreach (var nivelId in form.Niveis)
        {
            var item = new NivelUsuario() { nivelid = checkbox.nivelid, usuarioid = form.usuarioid };
            db.NivelUsuario.Add(item);
        }


        if (db.Usuario.Any(u => u.nome == form.nome))
            ModelState.AddModelError("nome", "O nome do usuario precisa ser unico.");

        if (!ModelState.IsValid)
            return View(form);

        usr.descricao = form.descricao;
        usr.nome = form.nome;
        usr.SetPassword(form.senha);

        db.Usuario.Add(usr);
        db.SaveChanges();

        return RedirectToAction("Index");
    }

ViewModel

public class NivelCheckbox
{
    public int nivelid { get; set; }
    public bool IsChecked { get; set; }
    public string nome { get; set; }
}



public class UsuariosNovo
{
    public List<NivelCheckbox> Niveis { get; set; }

    [HiddenInput]
    public int usuarioid { get; set; }

    [Required(ErrorMessage = "Obrigatório informar a Descrição")]
    [Display(Name = "Descrição")]
    public string descricao { get; set; }

    [Required(ErrorMessage = "Obrigatório informar o Login")]
    [Display(Name = "Login")]
    public string nome { get; set; }

    [Required(ErrorMessage = "Obrigatório informar a Senha")]
    [Display(Name = "Senha"), DataType(DataType.Password)]
    public string senha { get; set; }
}

View

<div class="panel panel-default col-sm-10 col-sm-offset-2">
    <div class="panel-heading">Niveis</div>
    <div class="panel-body">
        <ul class="list-group">

            @for (var i = 0; i < Model.Niveis.Count; i++)
            {
                <li class="list-group-item">
                    @Html.Hidden("Niveis[" + i + "].nivelid", Model.Niveis[i].nivelid)
                    <label for="Niveis_@(i)__IsChecked">
                        @Html.CheckBox("Niveis[" + i + "].IsChecked", Model.Niveis[i].IsChecked)
                        @Model.Niveis[i].nome
                    </label>
                </li>
            }
        </ul>
    </div>
</div>

When this action is called an exception it is invoked:

  

23503: insertion or update in table "user_level" viola   foreign key constraint "user_level_level_level"

For the debug I made, the id's are reset to the controller, does anyone know where I'm going wrong? Or is there any more correct way to do this? ( Pass the level id and user to another table )

    
asked by anonymous 30.11.2015 / 16:34

2 answers

1

The problem is that things are missing here:

@for (var i = 0; i < Model.Niveis.Count; i++)
{
    <li class="list-group-item">
        @Html.Hidden("Niveis[" + i + "].nivelid", Model.Niveis[i].nivelid)
        <label for="Niveis_@(i)__IsChecked">
            @Html.CheckBox("Niveis[" + i + "].IsChecked", Model.Niveis[i].IsChecked)
            @Model.Niveis[i].nome
        </label>
    </li>
}

Missing line index, as below:

@for (var i = 0; i < Model.Niveis.Count; i++)
{
    <li class="list-group-item">
        <input type="hidden" name="Niveis.index" id="Niveis_index" value="@(i)" />
        @Html.Hidden("Niveis[" + i + "].nivelid", Model.Niveis[i].nivelid)
        <label for="Niveis_@(i)__IsChecked">
            @Html.CheckBox("Niveis[" + i + "].IsChecked", Model.Niveis[i].IsChecked)
            @Model.Niveis[i].nome
        </label>
    </li>
}

This makes ModelBinder better organize and define variables.

    
30.11.2015 / 17:41
0

I was able to solve the problem in the following way, I only changed the action:

Controller

[HttpPost, ValidateAntiForgeryToken]
    public ActionResult Novo(UsuariosNovo form)
    {
        var usr = new Usuario();

        if (db.Usuario.Any(u => u.nome == form.nome))
            ModelState.AddModelError("nome", "O nome do usuario precisa ser unico.");

        if (!ModelState.IsValid)
            return View(form);

        foreach (var nivelId in form.Niveis)
        {
            var item = new NivelUsuario() { nivelid = nivelId.nivelid, usuarioid = form.usuarioid };

            if (nivelId.IsChecked)
                db.NivelUsuario.Add(item);
        }

        usr.descricao = form.descricao;
        usr.nome = form.nome;
        usr.SetPassword(form.senha);

        db.Usuario.Add(usr);
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    
30.11.2015 / 18:13