Error submitting form with ASP MVC

Asked

Viewed 182 times

0

I am facing a problem submitting a form developed in ASP MVC. By clicking the save button the following error message is returned:

System.InvalidOperationException: 'Não existe item ViewData do tipo 'IEnumerable<SelectListItem>' que possui a chave 'DepartamentoSelecionado'.'

What could be this mistake?

The project is divided into 4 main files. The first is the Model

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace projetinho.Models
{
    public class UsuarioModel
    {
        public int Id { get; set; }

        [Required(ErrorMessage = "Um nome deverá ser informado!")]
        [StringLength(maximumLength: 50, MinimumLength = 3, ErrorMessage ="O nome deve conter no mínimo 3 e no máximo 50 caracteres.")]
        public string Nome { get; set; }

        public int Id_Departamento { get; set; }

        public List<SelectListItem> DepartamentoSelecionado { get; set; }

        public UsuarioModel()
        {
        DepartamentoSelecionado = new List<SelectListItem>();
        }   
    }
}

The second file is a class that will manipulate the database

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace projeto.Models
{
public class UsuarioHandler
{
    private SqlConnection con;
    private void Conexao()
    {
        string stringConexao = ConfigurationManager.ConnectionStrings["sqlServer"].ToString();
        con = new SqlConnection(stringConexao);
    }

    public bool CadastraUsuario(UsuarioModel Usulist)
    {
        Conexao();
        string query = "insert into usuario(nome, id_departamento) values ('" + Usulist.Nome + "', '" + Usulist.DepartamentoSelecionado + "')";
        SqlCommand cmd = new SqlCommand(query, con);

        con.Open();
        int i = cmd.ExecuteNonQuery();
        con.Close();

        if (i >= 1)
            return true;
        else
            return false;
    }

//FUNÇÃO QUE LISTA OS DEPARTAMENTOS NO DROPDOWN
        public List<UsuarioModel> DepList()
        {
            Conexao();

            List<UsuarioModel> listaDepartamento = new List<UsuarioModel>();

            string query = "select id, nome from departamento";
            SqlCommand cmd = new SqlCommand(query, con);

            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            DataTable dt = new DataTable();

            con.Open();
            adapter.Fill(dt);
            con.Close();

            foreach (DataRow dr in dt.Rows)
            {
                listaDepartamento.Add(new UsuarioModel
                {
                    Id = Convert.ToInt32(dr["id"]),
                    Nome = Convert.ToString(dr["nome"])
                });
            }
            return listaDepartamento;
        }
    }
}

The Controlleris defined as follows::

using projeto.Models;
using System.Data;
using System.Web.Mvc;

namespace projeto.Controllers
{
    public class UsuarioController : Controller
    {
        [HttpGet]
        public ActionResult Cadastrar()
        {
            UsuarioHandler usuarioHandler = new UsuarioHandler();
            ViewBag.departamentos = new SelectList(usuarioHandler.DepList(), "id", "nome");

            return View();
        }

        [HttpPost]
        public ActionResult Cadastrar(UsuarioModel Usulist)
        {
            if (ModelState.IsValid)
            {
                UsuarioHandler usuariohandler = new UsuarioHandler();

                if (usuariohandler.CadastraUsuario(Usulist))
                {
                    ViewBag.Msg = "<div class='alert alert-success alert-dismissable'><a href = '#' class='close' data-dismiss='alert' aria-label='close'>×</a> Cadastro realizado com sucesso!</div>";
                    ModelState.Clear();
                }
                else
                {
                    ViewBag.Msg = "<div class='alert alert-danger alert-dismissable'><a href = '#' class='close' data-dismiss='alert' aria-label='close'>×</a> Erro ao cadastrar!</div>";
                }
            }
            return View();
        }
    }
}

And finally, the View

@model projetinho.Models.UsuarioModel 

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="container">
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            <label>Informe o nome:</label>
            @Html.EditorFor(model => model.Nome, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Nome, "", new { @class = "text-danger" })
        </div>

        <div class="form-group">
            <label>Selecione um departamento: </label>
             @Html.DropDownListFor(model => model.DepartamentoSelecionado, ViewBag.departamentos as SelectList, new { @class = "form-control" })
        </div>

        <div class="form-group">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
}

3 answers

0

Dude, create a private method that populates your viewBags and call in actionResult Register in the verb GET and in the POST, the error message appears because even if successful or not when registering, the registration view is called again, but this time without the populated viewBags!

A viewBag has the lifespan of 1 request, when you call the registration screen it is populated 1 Request, when a post is made (2 request) they no longer exist.

0

Friend,

See if that solves your problem:

In your Model initialize your List.

public UsuarioModel() {
     DepartamentoSelecionado = new List<SelectListItem>();
}
  • 1

    Good morning, even if you start the list on the model, the same error happens: System.Invalidoperationexception: 'There is no Viewdata item of type 'Ienumerable<Selectlistitem>' that has the 'Departmentselected' key'.'

0


There were two errors in my code that returned errors in the registration. The first was in the function you insert into the database:

 public bool CadastraUsuario(UsuarioModel Usulist)
    {
    // código omitido

        string query = "insert into usuario(nome, id_departamento) values ('" + Usulist.Nome + "', '" + Usulist.DepartamentoSelecionado + "')";

    // código omitido
    }

At the end of the string, I was passing the string that selected the department. The correct is to pass the ID of the selected department. in the case was:

 public bool CadastraUsuario(UsuarioModel Usulist)
    {
    // código omitido

        string query = "insert into usuario(nome, id_departamento) values ('" + Usulist.Nome + "', '" + Usulist.Id_Departamento + "')";

    // código omitido
    }

Another mistake was in ViewBag, within the View

  @Html.DropDownListFor(model => model.DepartamentoSelecionado, ViewBag.departamentos as SelectList, new { @class = "form-control" })

I changed it so that the model receive the Id_Departamento instead of receiving Department listing string (DepartamentoSelecionado) and registered.

Browser other questions tagged

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