Search code examples
asp.net-mvcasp.net-mvc-3razorextension-methods

How can I get access to ValidationMessageFor from an extension method


How can I get access to the HTML extensions ...For like LabelFor, EditorFor, ValidationMessageFor

I'm writing my own extension like that

Imports System
Imports System.Web.Mvc
Imports System.Web.Mvc.Html
Imports System.Web
Imports System.Text

Public Module HtmlExtensions
    <System.Runtime.CompilerServices.Extension()> _
    Public Function Asistente(Of TModel As Class)(ByVal helper As HtmlHelper, model As TModel) As MvcHtmlString
        helper.ValidationMessage("Home") 'It works fine
        helper.ValidationMessagefor()    'It show the next message 'ValidationMessagefor' is not a member of 'System.Web.Mvc.HtmlHelper     
    End Function

...

Actually it's because I want to produce a mvcHtmlString like that

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

Solution

  • The ValidationMessageFor method requires a generic type html helper. So your method should probably look something like this:

    Public Shared Function Asistente(Of TModel, TProperty)(helper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty))) As HtmlString
        Return helper.ValidationMessageFor(expression)
    End Function
    

    This will allow you to use that extension for any model and your call wouldn't change. I'm not entirely sure of what you're asking though.

    **@Html.Asistente(Function(model) model.Numero)**
    

    (note that vb was produced using a c# to vb converter - but it looks right)

    If you want to use the first sample you posted then you're going to have to write it something like this:

    Public Shared Function Test(Of T As User)(helper As HtmlHelper(Of T), model As T) As HtmlString
        Return helper.ValidationMessageFor(Function(f) f.Name)
    End Function
    

    However, that's a specific use case because if you don't force the model type to a specific type then you won't get the lambda expression properties to show up and thus won't compile.