Michael Thompson
Michael Thompson

Reputation: 31

How to Populate a DropDown List using Razor and MVC?

I am trying to populate & bind a drop down list control in MVC using Dapper, and I am having trouble finding a good example online. I can find plenty of examples of how to bind a statically defined drop down to a update a database (Like "Male" or "Female") and can get that to work. I can also find many examples of populating a drop down from a database, but I cannot get them to work in conjunction.

I just want my ProjectManifest/Create form to have a drop down populated with my current Projects.

I wish I was better at asking this question, but I do not know what I am doing wrong. I have tried dozens of variations in my code and different tutorials and questions on StackOverflow. The errors I receive from Visual Studio are so unhelpful, they are usually just NullReference exceptions, and there are so many variables in the HTML Helper function call I do not even know what is null.

These are some of the articles I have tried to use to help understand my problem:

I think the problem is in my index file, I do not understand Lambda expressions or what the expectation is to be in the arguments for the Html helper "DropDownListFor" or "DropDownList"

Index view

@using (Html.BeginForm("Index", "ProjectManifests", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    ....
    @Html.LabelFor(model => model.ManifestID)
    @Html.EditorFor(model => model.ManifestID)
    @Html.ValidationMessageFor(model => model.ManifestID)

    @Html.DropDownListFor(model => model.ProjectID, Model.Projects)
    ....

    <input type="submit" value="Create" class="btn btn-default" />
}

Controller

public class ProjectManifestsController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        Models.ProjectManifestModel model = new Models.ProjectManifestModel();
        DatabaseHelper.ConnectionString = ConfigurationManager.ConnectionStrings["MTConnectionString"].ConnectionString;
        ProjectRepository pr = new ProjectRepository();
        List<SelectListItem> projects = new List<SelectListItem>();
        foreach (Project p in pr.GetProjects())
        {
            projects.Add(new SelectListItem { Value = p.ProjectID.ToString(), Text = p.ProjectName });
        }
        model.Projects = projects;
        ViewBag.Projects = projects;
        return View();
    }
}

ViewModel

public class ProjectManifestModel
{
    [Key]
    public int ManifestID { get; set; }
    public int ProjectID { get; set; }
    ....
    public HttpPostedFileBase Attachment { get; set; }
    public IEnumerable<SelectListItem> Projects { get; set; }

}

The state of this code produces a different error, my apologies:

Compiler Error Message: CS1503: Argument 3: cannot convert from 'System.Collections.Generic.IEnumerable<Poscarp.TabLibrary.Project>' to 'System.Collections.Generic.IEnumerable<System.Web.Mvc.SelectListItem>'

Source Error:

Line 29: @Html.DropDownListFor(model => model.ProjectID, Model.Projects)

Upvotes: 2

Views: 3739

Answers (2)

jyrkim
jyrkim

Reputation: 2869

In the Index method of ProjectManifestsController, have you tried saving SelectListItems to SelectList and passing the SelectList to the view in ViewBag? Like this:

var selectList = new SelectList(projects, "Value", "Text");
ViewBag.SelectList = selectList;

Update, if you have specific ProjectID you need to have selected in the DropDownList, then pass it as the fourth parameter to the SelectList

var selectList = new SelectList(projects, "Value", "Text", "ProjectID");
ViewBag.SelectList = selectList;

Alternatively you can set one of SelectListItems to Selected in the foreach loop.

Index method

    [HttpGet]
    public ActionResult Index()
    {
        Models.ProjectManifestModel model = new Models.ProjectManifestModel();
        DatabaseHelper.ConnectionString = ConfigurationManager.ConnectionStrings["MTConnectionString"].ConnectionString;
        ProjectRepository pr = new ProjectRepository();
        List<SelectListItem> projects = new List<SelectListItem>();
        foreach (Project p in pr.GetProjects())
        {
            projects.Add(new SelectListItem { Value = p.ProjectID.ToString(), Text = p.ProjectName });
        }
        model.Projects = projects;
        ViewBag.Projects = projects;
        //new code below
        var selectList = new SelectList(projects, "Value", "Text");
        ViewBag.SelectList = selectList;
        return View();
    }

In the Index view, you can use @Html.DropDownList helper with the SelectList from the ViewBag after casting it:

 @Html.DropDownList("ProjectID", (SelectList)@ViewBag.SelectList)

Same as above, but this time there’s also option label (“-select-“) and HTML attributes used

@Html.DropDownList("ProjectID", (SelectList)@ViewBag.SelectList, "-select-", htmlAttributes: new { @class = "form-control" })

I hope this helps

Upvotes: 0

karritos
karritos

Reputation: 344

Assuming that ProjectManifestModel is the model in index.cshtml, try the following:

return View(model);

It looks like he's taking another class as a model.

Upvotes: 1

Related Questions