Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying data in a SelectList in ASP.NET Core

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>
like image 859
EB. Avatar asked Oct 03 '16 15:10

EB.


3 Answers

(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

like image 76
Dai Avatar answered Oct 20 '22 10:10

Dai


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; }
    }
like image 45
hakantopuz Avatar answered Oct 20 '22 09:10

hakantopuz


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();
    }
}
like image 39
Richard Marskell - Drackir Avatar answered Oct 20 '22 08:10

Richard Marskell - Drackir