ASP MVC 4: Request value of DropDownListFor

I have two classes many-to-many the first is "Anuncios" and the second "SubCategorias"

public class Anuncios {
    public int AnuncioId {get;set;}
    public string Titulo {get;set;}
    public ICollection<SubCategorias> SubCategorias {get;set;}
}

public class SubCategorias {
    public int SubCategoriaId {get;set;}
    public string Nome {get;set;}
    public ICollection<Anuncios> Anuncios {get;set;}
}

In DAL layer I did method to save the "Anuncio" in DB.

public void Salvar(Anuncio entidade)  {
     entidade.SubCategorias = entidade.SubCategorias.Select(subcat => _contexto.SubCategorias.FirstOrDefault(x => x.SubCategoriaId == subcat.SubCategoriaId)).ToList();
     _contexto.Anuncios.Add(entidade);
     _contexto.SaveChanges();
}

I Create the Action "Create":

private readonly Context _ctx = new Context();

public ActionResult Create()
{
    var model = new Anuncios {SubCategorias = _ctx.SubCategorias.ToList()};
    return View(model);
}

In View I made DropDownList with "SubCategorias":

@Html.LabelFor(model => model.SubCategorias)
@Html.DropDownListFor(model => model.SubCategorias, new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))

The DropDownListFor is populated with sucess..

Fine....

But when submit form the value selected in DropDownListFor not pass to method Create. The anuncio.SubCategorias is null!

private readonly AnunciosDal _anuncio = new AnunciosDal();

[HttpPost]
public ActionResult Create(Anuncio anuncio)
{
    _anuncio.Salvar(anuncio);
    return View(anuncio);
}

I have sought in various forums the solution, but could not find

Somebody help me?!

Sorry about my english rs...

Thank You! Fabrício Oliveira

Upvotes: 0

Views: 97

Answers (4)

Kevin
Kevin

Reputation: 160

You need to provide a collection of SelectListItems that populate your DropDownList as well as a property to hold the currently selected SelectListItems' Id (which will be posted back to the server):

public class Anuncios {
    public int AnuncioId {get;set;}
    public string Titulo {get;set;}
    public ICollection<SubCategorias> SubCategorias {get;set;}

    public int SelectedSubCategoryId {get;set;}
    public IEnumerable<SelectListItem> SubCategoryListItems {get;set;}
}

then, present them to the user via:

@html.DropDownListfor(x => x.SelectedSubCategoryId, Model.SubCategoryListItems)

The SubCategoryListItems will have to be populated from the server, typically something like this:

this.SubCategoryListItems = this.SubCategorias.Select(x => new SelectListItem { Text = x.Name, Value = x.Id });

Upvotes: 0

Shyju
Shyju

Reputation: 218722

You need to have another property to store the selected value from the dropdown. It is best if you create a viewmodel with properties which are needed for your view.

public class CreateAnuncios
{
  public string Title {set;get;}
  public int SelectedSubCategoryId {set;get;}
  public List<SelectListItem> SubCategories {set;get;}

  public CreateAnuncios()
  {
    this.SubCategories = new List<SelectListItem>();
  }
}

Now in your create action, create an object of this view model, Fill the SubCategories property and send to the view.

public ActionResult Create()
{
  var vm=new CreateAnuncios();
  vm.SubCategories = ctx.SubCategorias
       .Select(s=> new SelectListItem
             { Value = s.SubCategoriaId .ToString(), 
               Text=s.Nome}).ToList();

  return View(vm);
}

Your create view should be strongly typed to the CreateAnuncios class

@model YourNameSpaceHere.CreateAnuncios
@using(Html.Beginform())
{
  @Html.TextBoxFor(s=>s.Title)
  @Html.DropdownListFor(s=>s.SelectedSubCategoryId,Model.SubCategories,"Select")
  <input type="submit" />
}

Now when user posts the form, Read the Properties of the posted model and use that to save to db.

[HttpPost]
public ActionResult Create(CreateAnuncios model)
{
  //Check for model.Title and model.SelectedSubCategoryId and use it to save
  // to do :Save and redirect
}

Upvotes: 1

Brian Mains
Brian Mains

Reputation: 50728

The first parameter of DropDownListFor needs to be the object holding the selected value, where the second parameter contains the list:

@Html.DropDownListFor(model => model.SOME_ID_FOR_SELECTED_VALUE, 
                  new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))

Currently the example you have also maps the same list as the first property. You should use an ID like @Maess suggested, and then bind it via:

@Html.DropDownListFor(model => model.SubCategoriaID, new SelectList(Model.SubCategorias, "SubCategoriaId", "Nome"))

Selecting a value will then post it back to the server to this SubCategoriaID field.

Upvotes: 4

Maess
Maess

Reputation: 4146

You need an id property for the SubCategoria you have it in your binding, but not in the model

public class Anuncios {
    public int AnuncioId {get;set;}
    public string Titulo {get;set;}
    public ICollection<SubCategorias> SubCategorias {get;set;}
    public int SubCategoriaId{get;set;}
}

Upvotes: -1

Related Questions