Pick up a selected item on Dropdownlistfor using an ASP.NET MVC Viewmodel

Asked

Viewed 1,383 times

2

I am trying to register a Subcategory that needs a Category. I have Subcategoriaviewmodel, where I created the fields public IEnumerable<CategoriaViewModel> Categorias { get; set; } and public Guid CategoriaId { get; set; }. Tbm have public virtual Categoria Categoria { get; set; } pro EF.

My question is: how I would implement for me to receive in my Controller the Category selected in View?

In my Viewmodel have it:

public class SubCategoriaViewModel
    {
        public SubCategoriaViewModel()
        {
        }

        [Key]
        public Guid SubCategoriaId { get; set; }

        [Required(ErrorMessage = ("Preencha o nome da SubCategoria."))]
        [MaxLength(60, ErrorMessage = ("Máximo {0} caracteres."))]
        [MinLength(1, ErrorMessage = ("Mínimo {0} caracteres."))]
        [DisplayName("Nome")]
        public string SubCategoriaNome { get; set; }

        public IEnumerable<CategoriaViewModel> Categorias { get; set; }
        public Guid CategoriaId { get; set; }

        //[ScaffoldColumn(false)]
        //public DomainValidation.Validation.ValidationResult ValidationResult { get; set; }

        public virtual Categoria Categoria { get; set; }
        //public ICollection<Produto> Produtos { get; set; }

    }

In my View have it:

<div class="form-group">
            @Html.LabelFor(model => model.Categoria, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @* Este aqui tá dando certo aparecer na tela, mas não imagino um implementação para pegar um item selecionado *@
                @Html.DropDownListFor(model => model.CategoriaId,
                 new SelectList(Model.Categorias, "CategoriaId", "CategoriaNome"), new { @class = "form-control" })

                @* Esse aqui é so pra teste *@
                @Html.DropDownListFor(model => model.CategoriaId,
                 new SelectList(Model.Categorias, "CategoriaId", "CategoriaNome"), ((IEnumerable < Categorias)), new { @class = "form-control" })
            </div>
        </div>

In my Controller of the Subcategory I have this:

 // GET: SubCategorias/Create
        public ActionResult Create()
        {
            subCategoriaViewModel.Categorias = _categoriaAppService.ObterTodas();
            return View(subCategoriaViewModel);
        }

        // POST: SubCategorias/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(
            SubCategoriaViewModel subCategoriaViewModel)
        {
            subCategoriaViewModel =
                _subCategoriaAppService
                .Adicionar(subCategoriaViewModel);


            return View(subCategoriaViewModel);
        }
  • 1

    Your model doesn’t come filled out when you post it? Your model.Categoriaid contains the chosen value in the dropdown.

  • @LP.Gonçalves You were really right. I was already with what I wanted, but I have another problem. When I add a new subcategory, the Dropdwonlist is empty. To fix this, I need to get off this screen and then go back to her.

  • @LP.Gonçalves Como faço para o Dorpdwonlist stay populated?

  • sorry for the delay, you managed ?

  • @LP.Gonçalves No problems. I still can’t get.

2 answers

1

How to receive the selected category in the dropdown?

When you use:

    @Html.DropDownListFor(model => model.CategoriaId,
                new SelectList(Model.Categorias, "CategoriaId", "CategoriaNome"), 
                new { @class = "form-control" })

Will be generated:

<select id="CategoriaId" name="CategoriaId">
    <option value="1">Categoria 1</option>
    <option value="2">Categoria 2</option>
                   .
                   .
                   .
    <option value="N">Categoria N</option>
</select>

This means that when you select an item in the dropdown, the field CategoriaId will receive the "value" that select generated.

Select by returning null:

When the post is performed, by your code, you are sending only the CategoriaId, but not the list, so it’s not filled in.

To solve this, just in the post, when you do the Return view, set again these lines (as shown in Pablo Vargas' reply):

subCategoriaViewModel.Categorias = _categoriaAppService.ObterTodas();
return View(subCategoriaViewModel); 

An alternative would be to run this get from the list directly on your template (if this doesn’t hurt your solution architecture), assign the list once and every time you do get that property checks if the list this set, if not, get it again.

  • 1

    I liked your explanation of Pablo Vargas' solution!

  • Your explanation helped me understand other concepts

  • 1

    Glad I could help.

1


Iago, I believe you only need to repopulate the categories in the post again.

// POST: SubCategorias/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(SubCategoriaViewModel subCategoriaViewModel)
{
    subCategoriaViewModel =
                _subCategoriaAppService
                .Adicionar(subCategoriaViewModel);

    subCategoriaViewModel.Categorias = _categoriaAppService.ObterTodas();
    return View(subCategoriaViewModel);
}
  • Thank you for your solution!

  • That’s really what was missing.

Browser other questions tagged

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