3

I've been following this tutorial which shows you how to populate a drop down list. However my create page doesn't show a drop down list at all but shows this

enter image description here

This is my drop down list code in my UserController.cs

private void PopulateAdministratorsDropDownList(object selectedAdministrator = null)
{
    var administratorQuery = from d in db.Administrators
                           orderby d.AdministratorTitle
                             select d;
    ViewBag.AdministratorID = new SelectList(administratorQuery, "AdministratorID", "AdministratorTitle", selectedAdministrator);
}

Views\User\Create.cshtml

@model RecreationalServicesTicketingSystem.Models.User
....
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>User</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.LastName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.LastName)
            @Html.ValidationMessageFor(model => model.LastName)
        </div>
        .... // more controls
        <div class="editor-label">
            @Html.LabelFor(model => model.AdministratorID)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.AdministratorID)
            @Html.ValidationMessageFor(model => model.AdministratorID)
        </div>
        ....
        <p>
            <input type="submit" value="Create" />
        </p>

    </fieldset>
}

UserController.cs

public ActionResult Create()
{
    PopulateAdministratorsDropDownList();
    return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "LastName, FirstMidName, EnrollmentDate,AdministratorID, DepartmentID, DepotID")]User user)
{
    try
    {
        if (ModelState.IsValid)
        {
            db.Users.Add(user);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    }
    catch (DataException /* dex */)
    {
        ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
    }
    PopulateAdministratorsDropDownList(user.AdministratorID);
    return View(user);
}

private void PopulateAdministratorsDropDownList(object selectedAdministrator = null)
{
    var administratorQuery = from d in db.Administrators
                             orderby d.AdministratorTitle
                             select d;
    ViewBag.AdministratorID = new SelectList(administratorQuery, "AdministratorID", "AdministratorTitle", selectedAdministrator);
}
3
  • 1
    Change it to @Html.DropDownListFor(m => m.AdministratorID, (SelectList)ViewBag.AdministratorList) - not that you need to change the name of the ViewBag property - it cannot be the same name as the property your binding to. Commented Mar 13, 2016 at 4:24
  • 1
    @Html.DropDownListFor(model => model.AdministratorID, (SelectList)ViewBag.AdministratorID) Commented Mar 13, 2016 at 4:26
  • 1
    Note also that there is no point adding the last parameter (selectedAdministrator) in the SelectList constructor - its ignored by the HtmlHelper when binding to a model property. Commented Mar 13, 2016 at 4:34

1 Answer 1

3

You say you're following the tut, but you don't follow it exactly. Instead use @Html.DropDownListFor when you want to get a dropdown.

In the link you posted they use the following for the Department dropdown; like so:

<div class="editor-label">
    @Html.LabelFor(model => model.DepartmentID, "Department")
</div>
<div class="editor-field">
    @Html.DropDownList("DepartmentID", String.Empty)
    @Html.ValidationMessageFor(model => model.DepartmentID)
</div>

but yours looks like:

<div class="editor-label">
    @Html.LabelFor(model => model.AdministratorID)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.AdministratorID)
    @Html.ValidationMessageFor(model => model.AdministratorID)
</div>

They're not equivalent.

Side note: The tutorial you following is not following best practice (using the strongly typed DropDownListFor() method), and using DropDownList() will also mean that you do not get any client side validation (if you inspect the generated html you will note there are no data-val-* attributes in the <select> tag). Instead, use

@Html.DropDownListFor(m => m.AdministratorID, (SelectList)ViewBag.AdministratorList, "Please select")

and change the name of your ViewBag property (it cannot be the same name as the property your binding to)

ViewBag.AdministratorList = new SelectList(administratorQuery, "AdministratorID", "AdministratorTitle")
Sign up to request clarification or add additional context in comments.

8 Comments

It's because they usually highlight the code in yellow for codes that need to be changed but they didn't do it for that part.
@JasonWan, that seems like a valid statement given the imgs.
@StephenMuecke I wouldn't mind you making a comment with your strongly typed version. Of course I don't want bad practice with my coding. @Html.DropDownListFor(m => m.AdministratorID, (SelectList)ViewBag.AdministratorList) Strongly Typed?
@ChiefTwoPencils Of course! You've answered my question which is more than enough.
@ChiefTwoPencils, I realize you were just following the code in the tutorial, so I have edited your answer to include 'best' practice :) (although best practice would also include using a view model with IEnumerable<SelectListItem> AdministratorList rather than using ViewBag)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.