How do I make a connected Dropdownlist with a model property?

Asked

Viewed 8,104 times

5

I have my class:

public class Topico
{
    public int Id { get; set; }
    public string Nome { get; set; }
    public string Observacao { get; set; }
}

and my Subtopic class

public class SubTopico
{
    public int Id { get; set; }
    public virtual Topico Topico { get; set; }
    public int? TopicoId { get; set; }
    public string Nome { get; set; }
    public string Observacao { get; set; }
}

On my controller I have:

public ActionResult Create()
{
    ViewBag.Topico = new SelectList(db.Topicoes, "Id", "Nome");
    return View();
}

and in my view I have my DropDownList

 @Html.DropDownList("Topico",string.Empty)

Until then it carries all topics, etc.

But I can’t make a bind in it by saving it. In my action to save

public ActionResult Create([Bind(Include="Id,Topico,Nome,Observacao")] SubTopico subtopico)
{
    if (ModelState.IsValid)
    {
        subtopico.TopicoId = Convert.ToInt32(Request.Params["Topico"]);
        db.SubTopicoes.Add(subtopico);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(subtopico);
}

It does not come Topic Id, even because the class is null. So I capture using Request.Params["Topico"];

How do I link my dropdownlist to my property public virtual Topico that I have in my Subtopic class

4 answers

11


The way you did, the first time of questioning, it would be like this:

public ActionResult Create()
{
    ViewBag.Topico = new SelectList(db.Topicoes, "Id", "Nome");
    return View();
}

Na View:

@Html.DropDownList("TopicoId", ViewBag.Topico as SelectList)

or

@Html.DropDownListFor(model => model.TopicoId, ViewBag.Topico as SelectList)
  • Very good @user6026 solved my error!

5

Use @DropDownListFor:

@Html.DropDownList(model => model.TopicoId, ((IEnumerable)ViewBag.Topicos).Select(option => new SelectListItem {
    Text = option.Nome, 
    Value = option.Id.Value, 
    Selected = (Model != null) && (option.Id == (int)Model.TopicoId ?? 0)
}, "Selecione..."))

So you don’t need to use Request.Params, that it’s not exactly safe.

In this case the POST, Topico will come null even. It is loaded in the selection of data, as for example if you detail the Subtopico using

context.Subtopicos.Include(st => st.Topico).FirstOrDefault();

Finally, you can simplify your Controller for:

public ActionResult Create([Bind(Include="Id,TopicoId,Nome,Observacao")] SubTopico subtopico)
{
    if (ModelState.IsValid)
    {
        db.SubTopicoes.Add(subtopico);
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(subtopico);
}
  • Give an error by Placing this code in View, in Select

  • Have you changed from ViewBag.Topico for ViewBag.Topicos in his Controller?

  • Yes, I changed Viewbag.Topicos by Topico, is the same Viewbag controller

  • Okay, I need more details of the bug in order to help you. The full message helps me a lot.

4

One simple way I found and got it was:

In my controller, return a list:

ViewBag.Topicos = db.Topicoes.ToList();

And in my View use Dropdownlistfor as follows.

@Html.DropDownListFor(model => model.TopicoId, new SelectList(ViewBag.Topicos,"Id","Nome","Selecione..."))

3

It is also possible to use SQL query as data source for Dropdownlist:

No Controller:

public ActionResult NomeDaAction() {
    ViewBag.DadosDropDown = (from c in db.Tabela select c.ColunaDaTabela).Distinct();
    Return View();
}

In the View:

@Html.DropDownListFor(model => model.CampoOndeArmazenar, new SelectList(ViewBag.DadosDropDown, "Coluna1DaTabela", "OutraColunaDaTabela"), htmlAttributes: new { @class = "ClasseCSSdoDropDownList" })

Since, in the view, if you don’t want to assign a CSS class to the checkbox, simply remove the htmlAttributes command as below:

@Html.DropDownListFor(model => model.CampoOndeArmazenar, new SelectList(ViewBag.DadosDropDown, "Coluna1DaTabela", "OutraColunaDaTabela"))

Browser other questions tagged

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