0

Currently I am working with ASP.Net MVC 6 using EF7. I am using the default controller generator. For some reason my drop downs are not populating with data on the create or edit page even though data is present.

Just to clarify the 3 select lists are being populated by 3 different tables that are all connected to the main table I am adding to.

Here's what I got.

Controller code

private readonly SchoolContext _context;

public SchoolsController(SchoolContext context)
{
    _context = context;    
}

public IActionResult Create()
{
   ViewData["DistrictId"] = new SelectList(_context.Districts, "DistrictId", "District");
   ViewData["LocationId"] = new SelectList(_context.Locations, "LocationId", "Location");
   ViewData["TierId"] = new SelectList(_context.Tiers, "TierId", "Tier");
   return View();
}

View code

@model School

is included at the top and here is what one of the select element looks like

<div class="form-group">
        <label asp-for="DistrictId" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <select asp-for="DistrictId" class ="form-control"></select>
        </div>
    </div>

The select lists are completely blank with no errors there is data.

This is all generated automatically so I am totally clueless on what went wrong. Any suggestions?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
G_Man
  • 1,323
  • 2
  • 21
  • 33
  • 2
    What is `School`? Is it your ViewModel or entity? Why are you using `ViewData` instead of your `School` class? – Kosala W Jan 15 '16 at 21:58
  • School is the data entity that includes the 3 IDs for those fields, they come from 3 Navigation Property tables. The reason I am using ViewData is I am sending the information from those 3 separate tables so I have the name not just the ID to populate the lists with. – G_Man Jan 15 '16 at 22:08
  • You have to use a ViewModel for that. Are you familiar with that pattern? – Kosala W Jan 15 '16 at 22:13
  • Can you add School entity in your post? You need a model for the view or ViewModel. Btw, in your view, I don't see the School model being used. – joordan831 Jan 15 '16 at 22:13
  • ok I do not have a ViewModel setup. Didn't know that was needed to make this operate properly. I will try to get it setup. Are you asking me to include the model for School? – G_Man Jan 15 '16 at 22:22
  • I have no idea why you have accepted a wrong answer (and is not even using TagHelpers). For a dropdownlist to work correctly, you need a property to bind to - say `int District` - and an `IEnumerable` for the options - say `SelectList DistrictList` - and they should not have the same name. Then its `` –  Jan 16 '16 at 09:25
  • I accepted the answer before doing any additional testing then left work for the weekend. Re-opened it to get it figured it out. – G_Man Jan 17 '16 at 20:37

2 Answers2

1

Assuming your view name is School (the convention for ViewModel is name of the view + "ViewModel")

class SchoolViewModel
{
    IEnumerable<SelectListItem> Districts;
    IEnumerable<SelectListItem> Locations;
    IEnumerable<SelectListItem> Tiers;
}

Then in your view,

@model SchoolViewModel
...
@Html.DropDownList("Districts", m=>m.Districts, "-- Select--")
@Html.DropDownList("Locations", m=>m.Locations, "-- Select--")
@Html.DropDownList("Tiers", m=>m.Tiers, "-- Select--")

In your controller

public IActionResult Create()
{
    var vm = new SchoolViewModel();
    vm.Districts = _context.Districts.Select(d => new
    {
        Text = d.District,
        Value = d.DistrictId.ToString()
    };

    //repeat for others...

    return View(vm);
}
joordan831
  • 720
  • 5
  • 6
1

You need both a property to bind to (the selected value) and a property for the options and they need to have different names. Ideally you should be using a view model which would have (say)

public class SchoolVM
{
  public int DistrictId { get; set; }
  public IEnumerable<SelectListItem> DistrictList { get; set; }
  ....

and in the GET method

public IActionResult Create()
{
  SchoolVM model = new SchoolVM
  {
    DistrictList = new SelectList(_context.Districts, "DistrictId", "District"),
    .....
  };
  return View(model);
}

and in the view

@model SchoolVM
....
<select asp-for="DistrictId" asp-items="Model.DistrictList"></select>

alternatively, you could use ViewBag or ViewData and use

<select asp-for="DistrictId" asp-items="ViewBag.DistrictList"></select>
  • This actually cause my app to break. An exception of type 'System.InvalidOperationException' occurred in EntityFramework.Core.dll but was not handled in user code Additional information: The entity type 'Microsoft.AspNet.Mvc.Rendering.SelectListGroup' requires a key to be defined. – G_Man Jan 18 '16 at 20:34
  • Apparently public IEnumerable DistrictList { get; set; } should not be part of my EF model. – G_Man Jan 18 '16 at 20:35
  • I moved those statements to a view model to correct this and it worked. – G_Man Jan 18 '16 at 20:51
  • No it shouldn't - that why its a view model (not a data model) –  Jan 18 '16 at 20:51
  • You are right I was putting them in a controller instead of a view model. Thanks! – G_Man Jan 18 '16 at 20:52
  • Just came across you subsequent question (which explained the confusion). Using a view model, especially when editing, is always recommended and its worth reading the answers to [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc) –  Jan 18 '16 at 21:26