asp.net-mvcasp.net-core-mvcviewmodelselectlistitem

How to get integer LocationId into ViewModel from ListItem?


In my form, I have a DropDownList in which I am populating the data from table Locations from my Database. When the user selects the LocationName, the corresponding LocationId should get saved into the ViewModel so that I can pass it to the POST method to save the data into the Database. But, instead of getting the corresponding LocationId, I am getting 0.

Upon searching for the cause, I find that as ListItem needs the value and text fields in the form of string, while saving the data, I am forced to convert the LocationId into string using .ToString(). How can I get the LocationId to be stored into the ViewModel?

Code Snippets:

Controller

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 = locations;

    return View(locationsHistoryVM);
}

View

<label asp-for="LocationId" class="fg-labels" for="locationName"></label>
<select asp-for="LocationId" asp-items="ViewBag.Locations" class="chosen disabledropdowncntrl" data-placeholder="Choose a Location" name="locationName" id="dropDownLocationNames">
    <option value=""></option>
</select>

ViewModel

public int LocationId { get; set; }
public InventoryLocations Location { get; set; }

What to do?


Solution

  • When the form is posted, the parameters are named after name values of the inputs. So what is currently posted is locationName=5, because you have this in the select:

    name="locationName"
    

    Looks like you need to change this to

    name="locationId"
    

    to match the parameter name in the view model.

    And don't worry about string vs int, model binding should be able to figure it out.