简体   繁体   中英

Unable to Populate Dropdown from Database with MVC

Bear with me, I am new to MVC. I am trying to populate a dropdown list from a list function that retrieves integer values from the database. The dropdown currently shows the model name instead of values.

In my model, I have two functions for the AgentId I am trying to receive and have tried using both. I am uncertain on how this should actually be called.

Edit: I made a few changes and the list is now populating but I am unable to update the selected value. When I try to submit, I am getting this error in my view: "System.InvalidOperationException: 'There is no ViewData item of type 'IEnumerable' that has the key 'AgentId'.'"

Below is my updated code:

// customer model 
[DisplayName("Agent")]
public int AgentId { get; set; }

// list function
    public static List<int> GetAgentIdDropdown()
    {
        List<int> agentIdList = new List<int>();
        string getAgentIdQuery = @"SELECT AgentId FROM Agents";

        using (SqlConnection con = TravelExpertsConn.GetConnection())
        {
            using (SqlCommand cmd = new SqlCommand(getAgentIdQuery, con))
            {
                con.Open();
                SqlDataReader reader = cmd.ExecuteReader();
                Customer Agents = new Customer();
                while (reader.Read())
                {
                    Agents.AgentId = Convert.ToInt32(reader["AgentId"]);
                    agentIdList.Add(Agents.AgentId);
                }
                con.Close();
            }
        }
        return agentIdList;
    }

    // view
    @Html.DropDownListFor(model => model.AgentId, (IEnumerable<SelectListItem>)ViewBag.AgentId, "Select Agent ID", new { @class = "form-control" })  

    // controller
    public ActionResult Edit()
    {
        int id = Convert.ToInt32(Session["CustomerId"]);
        Customer currentCust = CustomerDB.CustomerDetails(id);
        ViewBag.AgentId = new SelectList(CustomerDB.GetAgentIdDropdown(), currentCust.AgentId);
        return View(currentCust);
    }

    // POST: Customer/Edit/5
    [HttpPost]
    public ActionResult Edit(Customer customer)
    {
        if (ModelState.IsValid)
        {
            try
            {
                int id = Convert.ToInt32(Session["CustomerId"]);
                CustomerDB.EditCustomer(id, customer);
                return RedirectToAction("Details");
            }
            catch
            {
                return View();
            }               
        }
        else
        {
            return View();
        }
    }

The DropDownListFor() method parameters should consist of first, the attribute of the model representing the selection by the user, which I'm guessing is your model.AgentId . The second parameter should be the IEnumerable property of the Model containing the options, or model.Agents

So one issue then is this line:

@Html.DropDownListFor(model => model.AgentId, ViewBag.Agents as SelectList, new { @class = "form-control" })

should look more like this:

@Html.DropDownListFor(model => model.AgentId, model.Agents, new { @class = "form-control" })

But more so, the model.Agents property is not going to actually return anything without a backing property. Here's a good example I've found online:

public class ViewModel
{
    private readonly List<IceCreamFlavor> _flavors;

    [Display(Name = "Favorite Flavor")]
    public int SelectedFlavorId { get; set; }

    public IEnumerable<SelectListItem> FlavorItems
    {
         get { return new SelectList(_flavors, "Id", "Name");}
    }
}

Notice how FlavorItems get method is returning a SelectList of the _flavors . Currently the code you've provided doesn't show any assignment of your GetAgentIdDropDown() to any property of the model, so I would try to match your Model's code with the convention I provided above, assign the results of GetAgentIdDropDown() to the backing property, and change the parameters of the @Html.DropDownListFor() as well.

I found the example from this link if you want to check it out. It's a bit older but there's only a minor difference in syntax.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM