4

我正在移植我之前在VS2013中使用的以前的MVC4.5 T4腳手架模板。一切進展順利,幸運的是,它背後的邏輯並沒有太大改變,但很多命名空間,對象和屬性都被重新命名,就像我預期的那樣。在VS2013中獲取自定義屬性T4腳手架模板

然而,棘手的位是PropertyInfo。似乎不再可能使用PropertyInfo,因爲新的ModelMetadata對象僅包含PropertyMetadata。由於PropertyMetadata沒有GetCustomAttributes()方法或類似的,我卡上升級下面的代碼片段:

<#+ 
string SearchableBy(PropertyInfo property) { 
    foreach (object attribute in property.GetCustomAttributes(true)) 
    { 
     var searchable = attribute as SearchableAttribute; 
     if (searchable != null) 
     { 
      return searchable.By == "" ? GetValueExpressionSuffix(property) : 
             searchable.By; 
     } 
    } 
    return null; 
} 
#> 
  • 是否有可能在T4控制器/視圖棚架獲得PropertyInfo對象不知何故?
  • 如果不是,訪問自定義註釋的新方法是什麼? ModelMetadata似乎對此

PS是無用的:
這個問題可以被視爲my previous one
如果你有興趣在如何自定義註釋可以在VS2012訪問的子問題,請this one

回答

0

我一直在摔跤這個特定的問題。我找到了一種解決方法,通過T4模板可用的EnvDTE服務訪問模型對象屬性的屬性集合。但是,這有點曲折,有一些限制。

創建EnvDTE服務實例後,需要引用包含您的EF DBContext的項目(假設您的MVC/WebAPI位於同一解決方案中的單獨項目中)。如果DBContext處於不同的解決方案中,並且不能通過EnvDTE服務獲得,那麼我不確定如果不引用EF程序集並使用反射就可以實現目標;但是這使得T4模板的便攜性降低。

下面是代碼草圖。在我的實際實現中,我有一個定位包含DBContext類的項目的例程。在我下面引用EF項目的名字,而不是。

var env = (DTE)((IServiceProvider)this.Host).GetService(typeof(EnvDTE.DTE)); 
var project = dte.Solution.Projects.OfType<Project>().Where(p => p.Name == "your ef project name").FirstOrDefault(); 

CodeType codeType = project.CodeModel.CodeTypeFromFullName("your ef namespace.class"); 
CodeClass cc = (CodeClass)codeType; 

List<CodeProperty> cps = cc.Members.OfType<CodeProperty>().ToList(); 

WriteLine(codeType.FullName); 
WriteLine("======================"); 

foreach (CodeProperty cp in cps) 
{ 
    WriteLine(cp.Name); 
    foreach (CodeAttribute ca in cp.Attributes.OfType<CodeAttribute>()) 
    { 
     WriteLine("-" + ca.Name); 
    } 
} 

如果您發現該屬性的attibutes集合爲空,這是因爲EF模型是不是在你引用的EnvDTE.Project。所以你肯定需要通過EF模型駐留的項目來訪問CodeClass對象。

再次,這是一個粗略的草圖......我相信你將需要調整這一點來得到所需的結果。我確信必須有更好的方法來做到這一點,但除了創建一個自定義腳手架,它使用屬性值擴展ModelMetadata類,我不確定更好的解決方案是什麼。

希望這是有道理的。

+1

嗯......我沒有時間去嘗試這個,但由於沒有人能夠在很長時間內做出貢獻,我會接受這個答案。一旦我有機會再次探究這一點,我會分享我的發現。乾杯! –

2

我已經寫了關於如何做到這一點這裏的教程:https://johniekarr.wordpress.com/2015/05/16/mvc-5-t4-templates-and-view-model-property-attributes/

與此自定義屬性

namespace CustomViewTemplate 
{ 
    [AttributeUsage(AttributeTargets.Property)] 
    public class RichTextAttribute : Attribute 
    { 
     public RichTextAttribute() { } 
    } 
} 

在你的實體,自定義屬性裝飾財產

namespace CustomViewTemplate.Models 
{  
    [Table("Person")] 
    public class Person 
    { 
     [Key] 
     public int PersonId { get; set;} 

     [MaxLength(5)] 
     public string Salutation { get; set; } 

     [MaxLength(50)] 
     public string FirstName { get; set; } 

     [MaxLength(50)] 
     public string LastName { get; set; } 

     [MaxLength(50)] 
     public string Title { get; set; } 

     [DataType(DataType.EmailAddress)] 
     [MaxLength(254)] 
     public string EmailAddress { get; set; } 

     [DataType(DataType.MultilineText)] 
     [RichText] \\ Custom Attribute 
     public string Biography { get; set; }  
    } 
} 

然後創建一個T4Helper,我們將在我們的模板中引用

using System; 

namespace CustomViewTemplate 
{ 
    public static class T4Helpers 
    { 
     public static bool IsRichText(string viewDataTypeName, string propertyName) 
     { 
      bool isRichText = false; 
      Attribute richText = null; 
      Type typeModel = Type.GetType(viewDataTypeName); 

      if (typeModel != null) 
      { 
       richText = (RichTextAttribute)Attribute.GetCustomAttribute(typeModel.GetProperty(propertyName), typeof(RichTextAttribute)); 
       return richText != null; 
      } 

      return isRichText; 
     } 
    } 
} 
相關問題