Catch a selected item in Dropdownlistfor using an ASP.NET MVC ViewModel

2

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

My question is : How would I implement to receive my Viewer on my Controller ?

In my ViewModel I have this:

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 I have this:

<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 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);
        }
    
asked by anonymous 17.02.2017 / 01:06

2 answers

1

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

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

    subCategoriaViewModel.Categorias = _categoriaAppService.ObterTodas();
    return View(subCategoriaViewModel);
}
    
19.02.2017 / 21:23
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" })

It 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 an item is selected in the dropdown, the CategoriaId field will receive the "value" of that select generated.

Select returning null:

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

To solve this, just in the post, when doing the return view, set these lines again (as shown in Pablo Vargas's answer):

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

An alternative would be to execute this get from the list directly in your model (if this does not hurt the architecture of your solution), assign the list once and every time you get the get of this property check if the list is set, get her back.

    
20.02.2017 / 17:31