Displaying data in a SelectList in ASP.NET Core
Asked Answered
D

5

11

I've tried a few different approaches. I'm not sure why but my SelectList/DropDown is empty. It shows no data. I'm not sure where I am going wrong.

I have an ASP.NET Core App. Entity Framework Core. Db First. I am using a repository pattern.

Here is my Model Class

public partial class Commodity
{
    public Guid Oid { get; set; }
    public string Code { get; set; }
}

This is my Interface:

interface ICommodityRepository
{
    IEnumerable<Commodity> GetAll();
}

My Repository:

public class CommodityRepository : ICommodityRepository
{
    private ltgwarehouseContext context;

    public CommodityRepository()
    { }

    public IEnumerable<Commodity> GetAll()
    {
        return context.Commodity.ToList();
    }
}

My Controller:

public class CommoditiesController : Controller
{
    static readonly CommodityRepository commodities = new CommodityRepository();

    public CommoditiesController(CommodityRepository commodities)
    { }

    // GET: /<controller>/
    public IEnumerable<Commodity> CommoditiesList()
    {
        return commodities.GetAll();
    }
}

This is my View/HTML Markup:

@model Lansing.BasisMap.Domain.Models.Commodity

<li><select asp-for="@Model.Code" asp-controller="Commodities" asp-action="CommoditiesList"></select> </li>
Doughboy answered 3/10, 2016 at 15:43 Comment(0)
M
15

(I'm not too familiar with the Tag Helper syntax in ASP.NET Core, but I'll give it a shot, anyone please correct me if I'm wrong)

  • The asp-for="" attribute does not need the @ prefix because it is not Razor code, the attribute value is already handled by ASP.NET's parser - you only need it if you're using C# syntax that is ambiguous with HTML (e.g. double-quotes).
  • The asp-controller and asp-action attributes do not apply to <select>
  • You are not providing any options to your <select>, use the asp-items attribute and provide IEnumerable<SelectListItem> or a SelectList instance. This can be passed in through your ViewModel or (my preference) through ViewData (or ViewBag).

Assuming it's ViewData, then:

public ActionResult YourControllerAction() {

    // stuff
    this.ViewData["items"] = commodities
        .GetAll()
        .Select( c => new SelectListItem() { Text = c.Code, Value = c.Oid.ToString() } )
        .ToList();

    // stuff
    return this.View( viewModel );
}

And use it in view like this:

<select asp-for="Model.Code" asp-items="@ViewData["items"]" />

There's a lot more examples in this QA posting: Select Tag Helper in ASP.NET Core MVC

Magnificent answered 3/10, 2016 at 16:7 Comment(1)
Hello, good answer, but for me I had to write <select name="PriceType" asp-for="PriceType" asp-items="@((List<SelectListItem>)(ViewData["PriceTypes"]))"></select> ... it shows, but doesn't send to backend (but thats another story)Interdictory
E
5

Try this:

In view:

<select asp-for="Staff.CityID" asp-items="@Model.CityList"></select>

In controller:

public IActionResult Create()
        {
            StaffViewModel model = new StaffViewModel();
            model.CityList = new List<SelectListItem>
            {
                new SelectListItem {Text = "İstanbul", Value = "1"},
                new SelectListItem {Text = "Sivas", Value = "2"}
            };

            return View(model);
        }

In model:

public class StaffViewModel
    {
        public  Staff Staff { get; set; }
        public  List<SelectListItem> CityList { get; set; }
    }
Einkorn answered 14/6, 2018 at 22:44 Comment(0)
M
1

It may be because you're not injecting the database into your CommodityRepository. You need to add the parameter to the constructor in order for the DI to work.

public CommodityRepository(ltgwarehouseContext ltgwc)
{
    context = ltgwc;
}

Then, if you want to have it automatically populated and injected into your controller, you need to register it in Startup.cs using one of the services.Addxxx methods. I recommend that you give the DI documentation a read as it will explain it better than I can.

Your final controller should look something like this:

public class CommoditiesController : Controller
{
    //Declare the local variable
    ICommodityRepository _commodities;
    //Load the repository via DI
    public CommoditiesController(CommodityRepository commodities)
    {
        //Set the local variable to the injected one
        _commodities = commodities;
    }

    // GET: /<controller>/
    public IEnumerable<Commodity> CommoditiesList()
    {
        //Reference the local variable in your methods
        return _commodities.GetAll();
    }
}
Monition answered 3/10, 2016 at 20:37 Comment(0)
D
0

In the view you can also do this:

@Html.DropDownListFor(model => model.ProvinceId, new SelectList(Model.provinces, "ID", "Description"), "Select Province"
                                        , new {
                                        @class = "form-select form-control", 
                                        id = "ProvinceDropDownList"})

And then the ViewModel will be

public class Places
{
    public string ProvinceId {get;set;}
    public IEnumerable<tblprovinceDTO> provinces { get; set; }
}
Dolichocephalic answered 22/6, 2022 at 13:7 Comment(0)
I
0

Controller :

SelectList selectList=New SelectList(yourItems,"IdField","TitleField");

You Can Send This Variable With Page Model Or ViewData

For Example :

ViewData["SelectListData"]=selectList;

View :

 <select asp-items="ViewData["SelectListData"]" class="form-control"></select>
Intrepid answered 26/6, 2022 at 13:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.