我创建了属性类来将元数据附加到属性,因此我可以显示表单输入字段的工具提示。
HelpAttribute
实施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
我在扩展方法中使用此元数据:
<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
所以我可以为我的任何模型属性调用Html.HelpFor
,如果它有适当的元数据,我会显示一个帮助图标,显示点击(js)上的工具提示。
只要HelpAttribute
在与我用其装饰属性的类相同的程序集中定义,一切正常。今天我不得不将HelpAttribute
移动到一个单独的dll(不同的命名空间),所以我这样做了,我引用了该项目并期望它能够工作。我没有得到任何编译器错误,该应用程序工作正常,但它不显示帮助图标。我调试了代码,我发现HelpAttribute
的构造函数被调用了具有正确文本的不同属性,但永远不会调用OnMetadataCreated
。有谁知道为什么会这样以及如何解决它?
答案 0 :(得分:14)
如果您引用了错误的命名空间,则可能无法调用此另一个原因。所以
using System.Web.ModelBinding;
将编译而不是被击中,但你应该使用
using System.Web.Mvc;
答案 1 :(得分:2)
我将再一次回答我的问题。显然在SO上发布内容有助于我解决问题。当我将HelpAttribute
移到单独的类库时,我必须为System.Web.Mvc
接口引用IMetadataAware
。我使用.NET 4.0
并且我自动引用了我之前安装的MVC4用于测试目的。它没有给我任何错误,它只是没有工作。当我将System.web.Mvc
更改为ver时。 3.0一切顺利。
答案 2 :(得分:-2)
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
namespace ColorPickerAttributeExample.Attributes
{
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public sealed class ColorPickerAttribute : Attribute, IMetadataAware
{
private const string Template =
"$('#{0}').ColorPicker({{onSubmit: function(hsb, hex, rgb, el) {{" +
"var self = $(el); self.val(hex);self.ColorPickerHide();}}, onBeforeShow: function () " +
"{{$(this).ColorPickerSetColor(this.value);}}}}).bind('keyup', function(){{ $(this).ColorPickerSetColor(this.value); }});";
public const string ColorPicker = "_ColorPicker";
private int _count;
// if using IoC container, you could inject this into the attribute
internal HttpContextBase Context
{
get { return new HttpContextWrapper(HttpContext.Current); }
}
public string Id
{
get { return "jquery-colorpicker-" + _count; }
}
#region IMetadataAware Members
public void OnMetadataCreated(ModelMetadata metadata)
{
IList<string> list = Context.Items["Scripts"] as IList<string> ?? new List<string>();
_count = list.Count;
metadata.TemplateHint = ColorPicker;
metadata.AdditionalValues[ColorPicker] = Id;
list.Add(string.Format(CultureInfo.InvariantCulture, Template, Id));
Context.Items["Scripts"] = list;
}
#endregion
}
}
using ColorPickerAttributeExample.Attributes;
using System;
namespace ColorPickerAttributeExample.Models
{
public class HomeModel
{
[ColorPicker]
public string ColorPicker { get; set; }
[ColorPicker]
public DateTime ColorPicker2 { get; set; }
}
}
@model dynamic
@{
var picker = ViewData.GetModelAttribute<ColorPickerAttribute>();
if (picker != null)
{
@Html.LabelForModel()
@Html.TextBoxFor(m => m, new {id = ViewData.ModelMetadata.AdditionalValues[ColorPickerAttribute.ColorPicker]})
}
}