views:

900

answers:

2

I have translated Jeremiah Clark's CheckBoxList Helper for MVC into my VB.Net project but when I try to use the method in my view I get the error

'CheckBoxList' is not a member of 'System.Web.Mvc.HtmlHelper(Of Attenda.Stargate.Web.UserRolesViewModel)'.

Can anyone tell me where I have gone wrong?

Helper module:

Imports System.Runtime.CompilerServices

Public Module InputExtensions

  <Extension()> _
  Public Function CheckBoxList(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal listInfo As List(Of ListItem)) As String
    Return htmlHelper.CheckBoxList(name, listInfo, DirectCast(Nothing, IDictionary(Of String, Object)))
  End Function

  <Extension()> _
  Public Function CheckBoxList(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal listInfo As List(Of ListItem), ByVal htmlAttributes As Object) As String
    Return htmlHelper.CheckBoxList(name, listInfo, DirectCast(New RouteValueDictionary(htmlAttributes), IDictionary(Of String, Object)))
  End Function

  <Extension()> _
  Public Function CheckBoxList(ByVal htmlHelper As HtmlHelper, ByVal name As String, ByVal listInfo As List(Of ListItem), ByVal htmlAttributes As IDictionary(Of String, Object)) As String
    If String.IsNullOrEmpty(name) Then
      Throw New ArgumentException("The argument must have a value", "name")
    End If
    If listInfo Is Nothing Then
      Throw New ArgumentNullException("listInfo")
    End If
    If listInfo.Count < 1 Then
      Throw New ArgumentException("The list must contain at least one value", "listInfo")
    End If
    Dim sb As New StringBuilder()
    For Each info As ListItem In listInfo
      Dim builder As New TagBuilder("input")
      If info.Selected Then
        builder.MergeAttribute("checked", "checked")
      End If
      builder.MergeAttributes(Of String, Object)(htmlAttributes)
      builder.MergeAttribute("type", "checkbox")
      builder.MergeAttribute("value", info.Value)
      builder.MergeAttribute("name", name)
      builder.InnerHtml = info.Text
      sb.Append(builder.ToString(TagRenderMode.Normal))
      sb.Append("<br />")
    Next
    Return sb.ToString()
  End Function

End Module

View source:

<%@ Page Title="" Language="VB" MasterPageFile="~/Views/Shared/TwoColumn.Master" Inherits="System.Web.Mvc.ViewPage(Of Attenda.Stargate.Web.UserRolesViewModel)" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
  Edit User Roles
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
  <h2>Edit Roles for
    <%=Html.Encode(Model.User.UserName)%></h2>
    <div>
    <%=Html.CheckBoxList("Roles", Model.Roles)%>
    </div>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="cphLeftPanel" runat="server">
</asp:Content>
+6  A: 

You need to import the namespace containing the custom helper class into your view page. You can do this on the page itself or in the web.config file for all pages. Put the code into a namespace first.

<%@ Import Namespace="MyProject.Extensions" %>

or (in the web.config)

<pages>
   ...
   <namespaces>
       ...
       <add namespace="MyProject.Extensions" />
   </namespaces>
</pages>
tvanfosson
Perfect, thanks :)
Nick
@tvanfosson: What are those parens in the `<%@ Imports %>` directive? I've never seen this syntax and think it's invalid. It should be `<%@ Imports Namespace="MyProject.Extensions" %>`.
Mehrdad Afshari
I've been doing a lot with attributes recently, you know: [Authorize(Roles="...")]. I've removed them.
tvanfosson
A: 

I encountered this problem because I hadn't declared the Module to be Public.

This question also asked here

Steven Hines