Dropdownlistfor with Viewbag and Dictonary returning null value

Asked

Viewed 85 times

0

I would like the help of all to assist in the following problem:

inserir a descrição da imagem aqui The error happens when it is still validating the fields.

Controller:

        public ActionResult Create()
    {
        var vEmpresas = new Dictionary<string, string>();
        vEmpresas.Add("Matriz", "Matriz");
        vEmpresas.Add("Filial1", "Filial1");
        vEmpresas.Add("Filial2", "Filial2");
        ViewBag.Empresas = vEmpresas;

        return View(model: new Suporte { Empresa = "Matriz"});
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Codigo,DataInicio,DescProblema,Empresa,Solicitante,Atendente,CodAtendimento,CodChamado,Solucao,Status")] Suporte suporte)
    {
        if (ModelState.IsValid)
        {
            db.SuporteAts.Add(suporte);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(suporte);
    }

View:

    <div class="form-group">
        @Html.LabelFor(model => model.Empresa, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownListFor(model => model.Empresa, new SelectList(ViewBag.Empresas, "key", "value",selectedValue: null) , new { @class = "form-control" } )
            @Html.ValidationMessageFor(model => model.Empresa, "", new { @class = "text-danger" })
        </div>
    </div>
  • This happens before saving or after?

  • What do you mean when you are validating? It was not clear, even load the page with the drop-down?

2 answers

2


As I mentioned in the comments on the other answer, the problem occurs when it returns to View after the validation of the data to ViewBag is not loaded with data.

In the Code below extracts the load of ViewBag in one method and I made his call in both Actions

public ActionResult Create()
{
    CarregaDropDownList();
    return View(model: new Suporte { Empresa = "Matriz"});
}


[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Codigo,DataInicio,DescProblema,Empresa,Solicitante,Atendente,CodAtendimento,CodChamado,Solucao,Status")] Suporte suporte)
{
    CarregaDropDownList();
    if (ModelState.IsValid)
    {
        db.SuporteAts.Add(suporte);
        db.SaveChanges();
        return RedirectToAction("Index");
    }   
    return View(suporte);
}

public void CarregaDropDownList()
{
    var vEmpresas = new Dictionary<string, string>();
    vEmpresas.Add("Matriz", "Matriz");
    vEmpresas.Add("Filial1", "Filial1");
    vEmpresas.Add("Filial2", "Filial2");
    ViewBag.Empresas = vEmpresas;
}

1

Try as follows: Creates a class called Company

public string codigo_empresa{ get; set; }
public string nome_empresa{ get; set; }

And just below the next:

public List<Empresas> ListaEmpresas(){

 List<Empresa> empresas= new List<Empresa>();
 empresas.Add(new Empresa
        {
            codigo_empresa = "Matriz",
            nome_empresa= "Matriz"
        });
  empresas.Add(new Empresa
        {
            cod_setor = "Filial1",
            nome_setor = "Filial1"
        });
  empresas.Add(new Empresa
        {
            cod_setor = "Filial2",
            nome_setor = "Filial2"
        });
 return empresas;

}

And then on the controller, you do so:

    public ActionResult Create()
    {
         ViewBag.Empresas = new SelectList(
            new Empresa().ListaEmpresas(), "codigo_empresa","nome_empresa");
        return View(model: new Suporte { Empresa = "Matriz"});
    }


    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Codigo,DataInicio,DescProblema,Empresa,Solicitante,Atendente,CodAtendimento,CodChamado,Solucao,Status")] Suporte suporte)
    {
        if (ModelState.IsValid)
        {
            db.SuporteAts.Add(suporte);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(suporte);
    }

And the dropdown goes like this:

 @Html.DropDownListFor(model => model.empresa, (IEnumerable<SelectListItem>)ViewBag.Empresas, new { @class = "form-control"})
  • This is nothing much different than what the AP already does, the error will still happen, and both in your code and in the AP, after the POST will give error because the Viewbag is not receiving the data again.

  • After the post he made a RedirectToAction("Index");, it does not need viewbag again, because viewbag is only required in the action Create()

  • Note that in your code and in the AP has a if (ModelState.IsValid) which returns to View if it is invalid. AP also talks about the question "The error happens when it is still validating the fields.". What’s he doing with Dictionary is not wrong. and in your answer there is no explanation of why create a class and switch to list.

  • Then just add the ViewBag.Empresas = new SelectList(&#xA; new Empresa().ListaEmpresas(), "codigo_empresa","nome_empresa"); at the beginning of HTTPPOST that will no longer give the error. Or the var vEmpresas = new Dictionary<string, string>();&#xA; vEmpresas.Add("Matriz", "Matriz");&#xA; vEmpresas.Add("Filial1", "Filial1");&#xA; vEmpresas.Add("Filial2", "Filial2");&#xA; ViewBag.Empresas = vEmpresas;, if he wants to keep using Dictionary

  • Maikeaerosmith and Barbetta, Tests the two forms mentioned above and both worked out. Thank you so much for your help.

  • @Charlesandrade, if you can mark the answer as right and vote, thank you!

Show 1 more comment

Browser other questions tagged

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