Search code examples
asp.net-mvcasp.net-core-mvcviewmodelselectlistitem

Cannot implicitly convert type 'System.Collections.Generic.List<InventoryLocations>' to 'System.Collections.Generic.IEnumerable<SelectListItem>'


I am a beginner. I am working on this ASP.NET Core MVC project where I am trying to pass my ViewModel to my POST method by submitting my form so that I can save the data in the Database. As soon as my GET method finishes running, I see the following RuntimeBinderException:

RuntimeBinderException: Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?

View:

<div class="row">
    <div class="col-sm-4">
        <div class="input-group fg-float">
            <div class="fg-line form-chose">
                <label asp-for="LocationName" class="fg-labels" for="locationName"></label>
                    <select asp-for="LocationName" asp-items="ViewBag.Locations" class="chosen disabledropdowncntrl" data-placeholder="Choose a Location" name="locationName" id="dropDownLocationNames">
                        <option value=""></option>
                    </select>
            </div>
        </div>
    </div>
</div>

Controller:

// GET: ~/Inventory/Locate/Id
    public IActionResult Locate(int Id)
    {
        InventoryLocationsHistoryViewModel locationsHistoryVM = new InventoryLocationsHistoryViewModel();

        // Populating Locations DropDownList
        var locationsList = new List<InventoryLocations>();
        locationsList = _context.InventoryLocations.ToList();
        var locations = locationsList.OrderBy(l => l.LocationName).Select(us => new SelectListItem { Value = us.LocationId.ToString(), Text = us.LocationName }).ToList();
        ViewBag.Locations = locationsList;
        ...
        ...
        return View(locationsHistoryVM);
    }

ViewModel:

namespace BackOffice.Models.CustomModels
{
    public class InventoryLocationsHistoryViewModel
    {
        public string UserId { get; set; }
        //public ApplicationUser User { get; set; }

        public string OtherUser { get; set; }
        public string Comments { get; set; }

        public string LocationName { get; set; }
        public InventoryLocations Location { get; set; }

        public DateTime? FromDate { get; set; }
        public DateTime? ToDate { get; set; }
    }
}

What am I doing wrong?


Solution

  • You set your ViewBag.Locations incorrectly. You can also collapse down a lot of your code since you are bringing your entire list into memory to sort and select 2 columns. This will create a select statement that only selects only the 2 columns needed and perform the sort on the sql server side.

    // GET: ~/Inventory/Locate/Id
        public IActionResult Locate(int Id)
        {
            InventoryLocationsHistoryViewModel locationsHistoryVM = new InventoryLocationsHistoryViewModel();
    
    
            var locations = new SelectList(_context.InventoryLocations.OrderBy(l => l.LocationName)
                .ToDictionary(us => us.LocationId, us => us.LocationName), "Key", "Value");
            ViewBag.Locations = locations;
    
            ...
            ...
            return View(locationsHistoryVM);
        }