2012-03-09 17 views
6

Tôi đã tạo lớp thuộc tính để đính kèm siêu dữ liệu vào các thuộc tính, vì vậy tôi có thể hiển thị chú giải công cụ cho các trường nhập của biểu mẫu.IMetadataAware.OnMetadataCreated không bao giờ được gọi là

HelpAttribute thực hiện 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 

tôi sử dụng siêu dữ liệu này trong phương pháp khuyến nông của tôi:

<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 

Vì vậy, tôi có thể gọi Html.HelpFor cho bất kỳ tài sản mô hình của tôi và nếu nó có siêu dữ liệu thích hợp tôi hiển thị biểu tượng trợ giúp hiển thị chú giải công cụ khi nhấp (js).

Tất cả hoạt động tốt miễn là HelpAttribute được định nghĩa trong cùng một cụm từ như các lớp tôi trang trí các thuộc tính của chúng. Hôm nay tôi đã phải di chuyển HelpAttribute đến một dll riêng biệt (không gian tên khác nhau), vì vậy tôi đã làm điều đó, tôi tham chiếu dự án và dự kiến ​​nó hoạt động. Tôi không nhận được bất kỳ lỗi trình biên dịch, ứng dụng hoạt động tốt, nhưng nó không hiển thị các biểu tượng trợ giúp. Tôi debuggedd mã và tôi thấy rằng các nhà xây dựng của HelpAttribute được gọi là cho các thuộc tính khác nhau với một văn bản thích hợp, nhưng OnMetadataCreated không bao giờ được gọi. Có ai có một ý tưởng tại sao đó là và làm thế nào để sửa chữa nó?

Trả lời

2

Một lần nữa tôi sẽ tự trả lời câu hỏi của mình. Rõ ràng việc đăng những thứ trên SO giúp tôi cấu trúc vấn đề trong đầu. Khi tôi di chuyển HelpAttribute sang một thư viện lớp riêng biệt, tôi phải tham chiếu System.Web.Mvc cho giao diện IMetadataAware. Tôi sử dụng .NET 4.0 và tôi tự động tham chiếu MVC4 mà tôi đã cài đặt một số thời gian trước đây cho mục đích thử nghiệm. Nó đã không nhận được tôi bất kỳ lỗi nào, nó chỉ không hoạt động. Khi tôi thay đổi System.web.Mvc thành ver. 3.0 mọi thứ hoạt động suôn sẻ.

-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]}) 
    } 
} 
+0

Mã đăng ở đây không liên quan đến câu hỏi hỏi, nó chỉ là một thuộc tính soạn sẵn không có xem xét cho bối cảnh của vấn đề của OP. Ngay cả khi mã đã được sử dụng một số - nó không nên chỉ được unceremoniously đổ mà không có một số giải thích về những gì nó làm và làm thế nào nó trả lời câu hỏi ban đầu. – RobD

13

Một lý do khác có thể không được gọi là nếu bạn đã tham chiếu không gian tên sai. Vì vậy,

using System.Web.ModelBinding; 

sẽ biên dịch và không bị đánh, nhưng bạn nên sử dụng

using System.Web.Mvc; 
+0

Cảm ơn! Tôi không muốn tưởng tượng phải mất bao lâu để tìm ra điều này. – Gerino