2011-05-24 24 views
1

我想在MVC視圖中訪問DataAnnotationGroupName。 例如,假設我的模特屬性之一是像如何在mvc視圖中訪問Dataannotation的「GroupName」?

[Display(Order = 1, GroupName= "Passport Detail", Name = "Passport #")] 
[Required()] 
[StringLength(20)] 
public string PassportNo { get; set; } 

現在,我怎麼可以在視圖訪問GroupName? 我想在MVC中實現類似this的內容。

回答

1

我找到了解決方法。
我們可以通過使用DataAnnotationsModelMetadataProvider來實現這一點。例如:

public class MetadataProvider : DataAnnotationsModelMetadataProvider 
{ 
    protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, 
                Type containerType, Func<object> modelAccessor, 
                Type modelType, string propertyName) 
    { 
     var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName); 

     var disp = attributes.OfType<DisplayAttribute>().FirstOrDefault(); 
     if (disp != null) 
     { 
      if (disp.GroupName != null) 
       metadata.AdditionalValues.Add("GroupName", disp.GroupName); 
     } 

     return metadata; 
    } 
} 

在我們可以用AdditionalValues照常MVC圖。

0

嗯,我沒有看到MVC使用它。 DataAnnotations實際上並不是MVC的一部分,所以所有的道具都不能使用。如果你想使用它,我會說你需要創建一個可以創建這些組的HTML助手。

好吧,我想我看你想要什麼......你想讓它爲你自動模板。只需使用EditorTemplates。 http://www.codecapers.com/post/Display-and-Editor-Templates-in-ASPNET-MVC-2.aspx

+0

感謝您的回覆。它幫助我找到解決方案。 – Rajkumar 2012-02-04 02:04:26

2

我正在研究這個,好像你必須爲一個屬性應該做很多代碼,應該只是在那裏......對嗎?

我不想延長當前的邏輯,而是用AdditionalValuesAttribute來定義我自己的「GroupName」。當然,你可以得到所有「神奇的褲子」延伸這一點,但它基本上就像這樣:

if (ViewData.ModelMetadata.AdditionalValues.ContainsKey("GroupName")) { 
     var groupName = ViewData.ModelMetadata.AdditionalValues["GroupName"].ToString(); 
    } 
0

這個怎麼樣!必須工作:

using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Web; 
using System.Web.Mvc; 

namespace System.Web.Mvc 
{ 
    public static class DisplayGroup 
    { 
     public static MvcHtmlString DisplayGroupName(this HtmlHelper helper, string groupName) 
     { 
      return MvcHtmlString.Create(groupName); 
     } 

     public static MvcHtmlString DisplayGroupNameFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 
     { 
      var type = typeof(TModel); 
      PropertyInfo propertyInfo = null; 

      var member = (MemberExpression)expression.Body; 
      var property = (PropertyInfo)member.Member; 
      var name = property.Name; 

      var metadataTypeInfo = type.GetCustomAttribute<MetadataTypeAttribute>(); 

      if (metadataTypeInfo != null) 
      { 
       var metadataType = metadataTypeInfo.MetadataClassType; 
       propertyInfo = metadataType.GetProperties().Where(x => x.Name == name).FirstOrDefault(); 
       if (propertyInfo == null) 
       { 
        propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault(); 
       } 
      } 
      else 
      { 
       propertyInfo = type.GetProperties().Where(x => x.Name == name).FirstOrDefault(); 
      } 

      string output = ""; 

      var dattr = propertyInfo.GetCustomAttribute<DisplayAttribute>(); 
      if (dattr != null) 
      { 
       if (dattr.GroupName == null) 
       { 
        output = propertyInfo.Name; 
       } 
       else 
       { 
        output = dattr.GroupName; 
       } 
      } 
      else 
      { 
       output = propertyInfo.Name; 
      } 

      return MvcHtmlString.Create(output); 
     } 

    } 
} 




public class MyModel 
    { 
     [Display(Name = "Number",GroupName="Invoice")] 
     string InvNo { get; set; } 
    } 

,然後簡單地寫:

@Html.DisplayGroupNameFor(x => x.InvNo) 

注: 命名空間應該是:System.Web.Mvc

更新: 很酷的事情是,如果你爲您的dataAnnotation定義了一個MetaDataType類,那麼這也將按預期工作編輯。