Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IMetadataAware.OnMetadataCreated is never called

I created attribute class to attach metadata to properties, so I can display tooltips for the form's input fields.

HelpAttribute implements IMetadataAware:

Public Class HelpAttribute
    Inherits Attribute
    Implements System.Web.Mvc.IMetadataAware

    Public Sub New(text As String)
        _text = text
    End Sub

    Private _text As String
    Public ReadOnly Property Text As String
        Get
            Return _text
        End Get
    End Property

    Public Sub OnMetadataCreated(metadata As System.Web.Mvc.ModelMetadata) Implements System.Web.Mvc.IMetadataAware.OnMetadataCreated
        metadata.AdditionalValues.Add("HelpText", _text)
    End Sub
End Class

I utilize this metadata in my extension method:

<Extension()>
Public Function HelpFor(Of TModel, TProperty)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TProperty))) As MvcHtmlString
    Dim metaData = ModelMetadata.FromLambdaExpression(Of TModel, TProperty)(expression, htmlHelper.ViewData)

    If metaData.AdditionalValues.ContainsKey("HelpText") Then
        Dim helpText = metaData.AdditionalValues("HelpText")
        Return MvcHtmlString.Create(String.Format("<span class=""help""></span><div class=""tooltip"" style=""display: none""><div class=""border-top""></div><div class=""close""><a href=""#"">close</a></div><br class=""clear""><div class=""content"">{1}</div></div>", htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(metaData.PropertyName), helpText, metaData.DisplayName))
    End If

    Return MvcHtmlString.Create(String.Format("<span class=""no_help""></span>", htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(metaData.PropertyName), metaData.DisplayName))
End Function

So I can call Html.HelpFor for any of my model's properties and if it has appropriate metadata I display a help icon which shows the tooltip on click (js).

That all works fine as long as HelpAttribute is defined in the same assembly as the classes that I decorate their properties with. Today I had to move HelpAttribute to a separate dll (different namespace as well), so I did that, I referenced the project and expected it to work. I do not get any compiler errors, the app works fine, but it does not display the help icons. I debuggedd the code and I see that the constructor of HelpAttribute is called for different properties with a proper text, but OnMetadataCreated is never called. Does anyone have an idea why that is and how to fix it?

like image 556
Michal B. Avatar asked Mar 09 '12 15:03

Michal B.


2 Answers

Another reason this may not be called is if you have the wrong namespace referenced. So

using System.Web.ModelBinding;

will compile and not be hit, but you should be using

using System.Web.Mvc;
like image 100
StuartQ Avatar answered Oct 13 '22 12:10

StuartQ


Once again I will answer my question myself. Apparently posting things on SO helps me structure the problem in my head. When I moved HelpAttribute to a seperate class library I had to reference System.Web.Mvc for IMetadataAware interface. I use .NET 4.0 and I automatically referenced MVC4 that I installed some time ago for testing purposes. It didn't get me any errors, it just did not work. When I changed System.web.Mvc to ver. 3.0 everything works smoothly.

like image 24
Michal B. Avatar answered Oct 13 '22 10:10

Michal B.