aweyeahdawg
aweyeahdawg

Reputation: 1026

MVC DropDownList Model Binding

I am trying to get the value of a custom SelectList to pass to the controller. My select list options are populated from a table in the db:

public class Priority
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

My viewmodel and model looks like this:

public class RequestViewModel
{
    public Request Request { get; set; }
    public IEnumerable<Priority> Priorities { get; set; }
}


public class Request
{
    public Guid Id { get; set; }
    public Priority Priority { get; set; }
}

Using

Html.DropDownListFor(x => x.Request.Priority, new SelectList(Model.Priorities, "Id", "Name", Model.Request.Priority), new { @class = "custom-select" })

the DropdownList is being populated correctly with the text and value.

When edited, the value of the dropdown list in the controller is null.

public IActionResult Edit(RequestViewModel viewModel)
{
    var priority = viewModel.Request.Priority; // this is null

}

Do I have to create a custom ModelBinder for this instance? Will the default model builder not get the correct selected 'Priority' from the Id passed in the value?

Also, is it best practice to use the ViewBag rather than the viewmodel to pass information like select lists to the view?

Upvotes: 0

Views: 3229

Answers (1)

kblau
kblau

Reputation: 2107

ASP.NET MVC Fiddle is here https://dotnetfiddle.net/PIPf4Z. In the meantime, I hope this answers your questions.

Controller/ViewModel

public class RequestViewModel
{
    public Guid SelectedGuid { get; set; }
    //Text=Name, Value=Guid
    public List<SelectListItem> Priorities { get; set; }
}

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Tut144(RequestViewModel selected)
    {
        RequestViewModel requestViewModel = GetData();
        return View();
    }

    public ActionResult Tut144()
    {
        RequestViewModel requestViewModel = GetData();

        return View(requestViewModel);
    }

    private static RequestViewModel GetData()
    {
        //prep the vcontroller-you can do this from db
        List<SelectListItem> list = new List<SelectListItem>();
        SelectListItem selectListItemA = new SelectListItem { Text = "Priority1", Value = Guid.NewGuid().ToString() };
        SelectListItem selectListItemB = new SelectListItem { Text = "Priority2", Value = Guid.NewGuid().ToString() };
        SelectListItem selectListItemC = new SelectListItem { Text = "Priority3", Value = Guid.NewGuid().ToString() };
        list.Add(selectListItemA);
        list.Add(selectListItemB);
        list.Add(selectListItemC);
        RequestViewModel requestViewModel = new RequestViewModel { Priorities = list };
        return requestViewModel;
    }

View

@model Testy20161006.Controllers.RequestViewModel
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Tut144</title>
</head>
<body>
    @using (Html.BeginForm())
    {
    <table>
        <tr>
            <td>Priority:</td>
            <td>
                @Html.DropDownListFor(m => m.SelectedGuid,
                         new SelectList(Model.Priorities, "Value", "Text"))
            </td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="Go" /></td>
        </tr>
    </table>
    }
</body>
</html>

Upvotes: 1

Related Questions