mrN
mrN

Reputation: 3774

Error using Drop Down List HTML Helper

In my controller, I have defined the select list items and the passed the list to the view as

Dim mySelectItems = New List(Of SelectListItem) From {
    New SelectListItem With {.Text = "First item", .Value = "1", .Selected = True}
}

ViewData("doctorList") = mySelectItems

Now, from my view, I am trying to feed the values into a DropDown List using the HTML Helper.

<label for="appointment_doctor">Select Doctor</label>
<%= Html.DropDownList("doctor", ViewData("doctorList"))%>

Now, I am thinking this should work but it is not.

Error Log:

Overload resolution failed because no accessible 'DropDownList' can be called without a narrowing conversion: Extension method 'Public Function DropDownList(name As String, selectList As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem)) As System.Web.Mvc.MvcHtmlString' defined in 'System.Web.Mvc.Html.SelectExtensions': Argument matching parameter 'selectList' narrows from 'Object' to 'System.Collections.Generic.IEnumerable(Of System.Web.Mvc.SelectListItem)'. Extension method 'Public Function DropDownList(name As String, optionLabel As String) As System.Web.Mvc.MvcHtmlString' defined in 'System.Web.Mvc.Html.SelectExtensions': Argument matching parameter 'optionLabel' narrows from 'Object' to 'String'. G:\Surgery\Surgery\Views\Appointment\Index.aspx 11 13 Surgery

Upvotes: 0

Views: 1560

Answers (1)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038730

Try casting:

<%= Html.DropDownList(
    "doctor", 
    CType(ViewData("doctorList"), IEnumerable(Of SelectListItem)) 
) %>

The cast is necessary because ViewBag is a dynamic type and extension methods (such as DropDownList) cannot be dispatched with dynamic parameters.

And by the way that's one of the millions of reasons why I prefer using a view model instead of ViewBag. It also allows you to use the strongly typed version of the helper:

<%= Html.DropDownList(
    Function(x) x.SelectedDoctorId, 
    Model.Doctors 
) %>

UPDATE:

As requested in the comments section here's a full example using a view model.

As always in an ASP.NET MVC application we start by defining our view model class that will reflect the requirements of your view which from your description so far I understood that it should display a dropdown list of doctors. You might will obviously need to enrich this view model with other properties in order to reflect your specific view requirements:

Public Class DoctorViewModel
    Property SelectedDoctorId As Integer
    Property Doctors As IEnumerable(Of SelectListItem)
End Class

then you could have a controller action that will populate this view model and pass it to the view:

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index() As ActionResult
        Dim model = New DoctorViewModel()

        ' TODO: those could come from a database or something
        ' I am hardcoding the values here for better understanding
        model.Doctors = {
            New SelectListItem With {.Value = "1", .Text = "doctor 1"},
            New SelectListItem With {.Value = "2", .Text = "doctor 2"},
            New SelectListItem With {.Value = "3", .Text = "doctor 3"}
        }

        Return View(model)
    End Function
End Class

and finally you will have a corresponding strongly typed view (~/Views/Home/Index.aspx):

<%@ Page 
    Language="VB" 
    MasterPageFile="~/Views/Shared/Site.Master" 
    Inherits="System.Web.Mvc.ViewPage(Of ToDD.DoctorViewModel)" %>

<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

    <%= Html.DropDownListFor(Function(x) x.SelectedDoctorId, Model.Doctors) %>

</asp:Content>

Upvotes: 3

Related Questions