1

I have a get page that renders the edit page that looks like this

    public ActionResult EditItemInstance(int id)
        {
            ItemInstance i = db.ItemInstances.Find(id);

            var item = (from it in db.Items.Where(x => x.deleted == false)
                        select new
                        {
                            itemID = it.ID,
                            itemName = it.ItemID + ": " + it.Name
                        }).OrderBy(x => x.itemName).ToList();

            ViewBag.ItemID = new SelectList(item, "itemID", "itemName", i.ItemID);
            return View(i);
        }

And in my view page I have a dropdown list that looks like this

 @Html.DropDownList("ItemID", null, "-- Select --", htmlAttributes: new { @class = "form-control chosen-select" })

I want the default value to be the value of the current item I am editing. For most of the items this works correctly. But when I edit some items I get a default value of '-- Select -- '

Why is the default value working for some items but coming up as 'select' for others?

2 Answers2

0

ViewBag and ViewData is not the best option to use. If you want to refactor this code soon - it will be hard to track changes you should make. Use it only if there is no any other option. However I cannot think about case like that.

Imagine that your model contains property SelectedItem of type SelectListItem and Items of type SelectList

Then use DrodownListFor @Html.DropDownListFor(m => m.SelectedItem, Model.Items)

  • I tried that but it didn't return the item I am currently editing as the default value. Maybe I had done something wrong though. Could you expand on your answer please? –  Jun 18 '20 at 21:41
  • Probably **default value** term puts some confusion. Default value - is the value, which will be shown when you don't have selected value. Selected value is the value which will be shown as selected when you start editing your form. You can checkout answer here. There was a similar question. https://stackoverflow.com/questions/39550804/what-is-the-best-ways-to-bind-html-dropdownlistfor-in-asp-net-mvc5 – Volodymyr Puzdriak Jun 18 '20 at 21:45
0

Yea don't use ViewBag and ViewData to pass around data if you don't have to. Use ViewModel instead because it's strongly-typed and you don't have to cast it on your view, and you can declare additional properties to suit your needs.

Again, I am not sure the relationship between your ItemInstance and the list of Items coming back from the database, but from what you're trying to do, I am guessing there is a dropdown on the side of your edit page, and whatever the current item instance being edited would be selected on the dropdown?

public class EditItemInstanceViewModel
{
    public IEnumerable<ItemOptionViewModel> AvailableItemOptions { get; set; }

    public ItemInstanceViewModel ItemInstance { get; set; }   
}

public class ItemOptionViewModel
{
    public int ItemId { get; set; }
    public string ItemName { get; set; }
}

public class ItemInstanceViewModel
{
    public int ItemInstanceId { get; set; }
    public string ItemInstanceName { get; set; }

    // ... there might be more properties
}

Then in your controller, you can fill EditItemInstanceViewModel like this:

public ActionResult EditItemInstance(int id)
{
    ItemInstance itemInstance = db.ItemInstances.Find(id);
    if (itemInstance == null)
    {
        return HttpNotFound();
    }

    var availableItemOptions = (from it in db.Items.Where(x => x.deleted == false)
        select new ItemOptionViewModel
        {
            ItemID = it.ID,
            ItemName = it.ItemID + ": " + it.Name
        })
        .OrderBy(x => x.ItemName)
        .ToList();

    var vm = new EditItemInstanceViewModel
    {
        AvailableItemOptions = availableItemOptions,
        ItemInstance = new ItemInstanceViewModel
        {
            ItemInstanceId = itemInstance.Id,
            ItemInstanceName = itemInstance.Name
        }
    };
    return View(vm);
}

Then on the view:

@model EditItemInstanceViewModel
@{

}

...

@Html.DropdownList("selected-item-id",
    <!-- Enumerable items; Dropdown value field; Dropdown text field; Selected value; -->
    new SelectList(Model.AvailableItemOptions, "ItemInstanceId", "ItemInstanceName", Model.ItemInstance.ItemInstanceId),
    "-- Select --",
    new { @class = "form-control chosen-select" })

...

enter image description here


Nice and clean!

David Liang
  • 20,385
  • 6
  • 44
  • 70