自定义htmlhelper并提供验证支持

Cha*_*ell 1 validation html-helper asp.net-mvc-3

我正在使用我自己的自定义HtmlHelper来启用选择列表上的AutoComplete支持.

这是正常的,除了我需要能够支持我的ViewModel中的DataAnnotations.

这是我当前(工作)HtmlHelper(没有验证)

    <Extension()>
    Public Function AutoCompleteDropDownList(ByVal helper As HtmlHelper, name As String, autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As MvcHtmlString
        Dim selectBuilder As New TagBuilder("select")
        selectBuilder.MergeAttribute("name", name)
        selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
        selectBuilder.MergeAttribute("autocorrect", "off")
        selectBuilder.MergeAttribute("autocomplete", "off")

        Dim selectListBuilder As New TagBuilder("option")
        selectListBuilder.MergeAttribute("value", "")
        selectListBuilder.MergeAttribute("selected", "selected")

        Dim innerHtmlBuilder As New StringBuilder
        innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))


        For Each item In autoCompleteSelectListItem
            selectListBuilder = New TagBuilder("option")
            selectListBuilder.MergeAttribute("value", item.Value)
            selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
            selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
            selectListBuilder.InnerHtml = item.Label
            innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
        Next

        selectBuilder.InnerHtml = innerHtmlBuilder.ToString()

        Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
    End Function
Run Code Online (Sandbox Code Playgroud)

如何重写这个以支持验证?就像是AutoCompleteDropDownListFor()

PS:C#解决方案是完全可以接受的,我正在研究的项目是VB,但我不介意翻译.


PS:我正在浏览http://aspnet.codeplex.com上的源代码,但我找不到任何引用DropDownListFor

Dar*_*rov 6

你必须下载源代码,你会发现里面的DropDownListFor助手的实现mvc3-rtm-sources.zip\mvc3-rtm-sources\mvc3\src\SystemWebMvc\Mvc\Html\SelectExtensions.cs.要启用客户端验证,您必须在下拉列表中发出HTML5 data-*属性.这是SelectInternal通过调用htmlHelper.GetUnobtrusiveValidationAttributes方法在方法结束时完成的.

<Extension()>
Public Function AutoCompleteDropDownList(ByVal helper As HtmlHelper, name As String, autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As MvcHtmlString
    Dim selectBuilder As New TagBuilder("select")
    selectBuilder.MergeAttribute("name", name)
    selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    selectBuilder.MergeAttribute("autocorrect", "off")
    selectBuilder.MergeAttribute("autocomplete", "off")

    Dim selectListBuilder As New TagBuilder("option")
    selectListBuilder.MergeAttribute("value", "")
    selectListBuilder.MergeAttribute("selected", "selected")

    Dim innerHtmlBuilder As New StringBuilder
    innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))


    For Each item In autoCompleteSelectListItem
        selectListBuilder = New TagBuilder("option")
        selectListBuilder.MergeAttribute("value", item.Value)
        selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
        selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
        selectListBuilder.InnerHtml = item.Label
        innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
    Next

    selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
    selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))

    Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function
Run Code Online (Sandbox Code Playgroud)

更新:

根据评论部分的要求,这里是一个强类型的帮助程序版本的样子:

<Extension()>
Public Function AutoCompleteDropDownListFor(Of TModel, TProperty)(helper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty)), autoCompleteSelectListItem As List(Of AutoCompleteSelectListItem), htmlAttributes As Object) As IHtmlString
    Dim name = ExpressionHelper.GetExpressionText(expression)
    Dim fullHtmlFieldName As String = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name)

    Dim selectBuilder = New TagBuilder("select")
    selectBuilder.MergeAttribute("name", fullHtmlFieldName)
    selectBuilder.MergeAttributes(New RouteValueDictionary(htmlAttributes))
    selectBuilder.MergeAttribute("autocorrect", "off")
    selectBuilder.MergeAttribute("autocomplete", "off")

    Dim selectListBuilder = New TagBuilder("option")
    selectListBuilder.MergeAttribute("value", "")
    selectListBuilder.MergeAttribute("selected", "selected")

    Dim innerHtmlBuilder = New StringBuilder()
    innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))

    For Each item In autoCompleteSelectListItem
        selectListBuilder = New TagBuilder("option")
        selectListBuilder.MergeAttribute("value", item.Value)
        selectListBuilder.MergeAttribute("data-alternative-spellings", item.AlternativeSpellings)
        selectListBuilder.MergeAttribute("data-relevancy-booster", item.RelevancyBooster)
        selectListBuilder.InnerHtml = item.Label
        innerHtmlBuilder.Append(selectListBuilder.ToString(TagRenderMode.Normal))
    Next

    selectBuilder.InnerHtml = innerHtmlBuilder.ToString()
    selectBuilder.MergeAttributes(helper.GetUnobtrusiveValidationAttributes(name))

    Return MvcHtmlString.Create(selectBuilder.ToString(TagRenderMode.Normal))
End Function
Run Code Online (Sandbox Code Playgroud)