2013-10-29 26 views
1

您可以为模型创建自定义数据注释,可以在T4模板中读取类似property的属性.Scaffold是否被读取?我想添加像Scaffold这样的数据注释参数,以便构建视图。MVC 4自定义数据注释在T4脚手架中读取

谢谢

+0

Ye当然是。你为什么不能? – McGarnagle

+0

谢谢:)关于如何的任何参考? – elector

+0

为自己说话,我没有时间去解决整个问题。 (到目前为止,这个问题只有9个观点:P)。如果你尝试/开始,我可能会提供帮助。 – McGarnagle

回答

4

所以,这就是你是如何做到的。 按照有关如何创建一个自定义属性本教程http://origin1tech.wordpress.com/2011/07/20/mvc-data-annotations-and-custom-attributes/

要在T4模板,脚手架阅读本属性值,首先添加模板文件此处描述http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx

然后,例如,开放式List.tt从AddView文件夹。该模板创建索引视图。

转到模板文件的末尾,找到类ModelProperty的定义。添加你的属性值(公共字符串MyAttributeValue {get; set;}

现在在List.tt中查找一下,找到bool Scaffold(PropertyInfo属性)方法,你需要添加你自己的属性属性阅读器这种方法,对于上面提到的教程,应该是:

string OptionalAttributesValueReader(PropertyInfo property){ 
    foreach (object attribute in property.GetCustomAttributes(true)) { 
     var attr = attribute as OptionalAttributes ; 
     if (attr != null) { 
       return attr.style; 
     } 
    } 
    return String.Empty; 
} 

然后在文件的底部找到相应的方法列表GetEligibleProperties(类型类型)你的读者加入到这样的:。

  ... 
      IsForeignKey = IsForeignKey(prop), 
      IsReadOnly = prop.GetSetMethod() == null, 
      Scaffold = Scaffold(prop), 
      MyAttributeValue = OptionalAttributesValueReader(prop) 

当你想使用和阅读这个属性,你可以不喜欢它的脚手架属性在List.tt

 List<ModelProperty> properties = GetModelProperties(mvcHost.ViewDataType); 
     foreach (ModelProperty property in properties) { 
      if (property.MyAttributeValue != String.Empty) { 
       //read the value 
       <#= property.MyAttributeValue #> 
      } 
     } 

使用因为这些类是在我的项目中定义的,我有我的项目的dll和命名空间添加到List.tt的顶部:

 <#@ assembly name="C:\myProjectPath\bin\myMVCproject.dll" #> 
    <#@ import namespace="myMVCproject.CustomAttributes" #> 

如果您的模型发生变化,您需要在脚手架中找到这些新更改,则需要重新构建您的项目。

希望任何人寻求的解决方案会发现这个有用。询问是否有什么不清楚的地方。

+1

这看起来像我所需要的,除了我使用MVC 5和模板看起来完全不同(无法找到您提到的模板中的任何位置)。你知道如何在MVC 5中做到这一点吗? –

+1

我还没有尝试过MVC5模板。我不认为我会在不久的将来为MVC 5做这种事情。但是,请,如果您确实找到了方法,请将其发布到此处。最终这种事情应该在博客文章中,对吧? – elector

+0

@NickThissen,你有没有在MVC 5中找到这个解决方案? –

2

这是我在MVC 5中做到的。我很久以前就做了这个,我可能会忘记东西,我只是复制/粘贴我在修改过的模板中看到的内容。

我需要一种方法来设置(例如)创建/编辑视图或列表视图表中的属性顺序。所以我创建了一个带有整数属性Order的自定义属性OrderAttribute

要在T4模板中访问此属性,我修改了文件ModelMetadataFunctions.cs.include.t4。在顶部,我增加了一个方法检索Order值从PropertyMetadata对象的属性设置,而另一种方法简单地通过订单订购的PropertyMetadata项目的列表:

List<PropertyMetadata> GetOrderedProperties(List<PropertyMetadata> properties, Type modelType) { 
    return properties.OrderBy<PropertyMetadata, int>(p => GetPropertyOrder(modelType, p)).ToList(); 
} 

int GetPropertyOrder(Type type, PropertyMetadata property) { 
    var info = type.GetProperty(property.PropertyName); 
    if (info != null) 
    { 
     var attr = info.GetCustomAttribute<OrderAttribute>(); 
     if (attr != null) 
     { 
      return attr.Order; 
     } 
    } 
    return int.MaxValue; 
} 

最后,在清单模板例如,我加入,我叫GetOrderedProperties方法的一部分:

var typeName = Assembly.CreateQualifiedName("AcCtc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", ViewDataTypeName); 
var modelType = Type.GetType(typeName); 

var properties = ModelMetadata.Properties.Where(p => p.Scaffold && !p.IsPrimaryKey && !p.IsForeignKey && !(p.IsAssociation && GetRelatedModelMetadata(p) == null)).ToList(); 
properties = GetOrderedProperties(properties, modelType); 

foreach (var property in properties) 
{ 
//... 
} 

不幸的是我所需要的项目的名称要能够创造出我需要得到从属性的Type对象。不理想,也许你可以用其他方式得到它,但是如果没有这个字符串,包括所有版本的东西,我都无法管理它。

5

我写了一篇关于我为MVC5提出的解决方案的博客文章。我在这里张贴的人谁走来: https://johniekarr.wordpress.com/2015/05/16/mvc-5-t4-templates-and-view-model-property-attributes/

编辑:在您的实体,装饰性能与自定义属性

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)] 
     public string Biography { get; set; }  
    } 
} 

与此自定义属性

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

然后创建一个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; 
     } 
    } 
} 
+0

这非常麻烦:(你应该这样做:从契约/模型集合中引用新的程序集(如果你想保持引用“简单”,你不会喜欢做什么),并添加引用T4模板中的同一个程序集使更复杂的开发环境设置)... –

+0

很想看到你的博客更新和VIew模板内获取数据类型的简化方式,不能相信MS拿出来! – transformer