您能否为模型创建自定义数据注释,以便在 T4 模板中读取类似属性的 View。Scaffold 已读取?我想添加数据注释参数,如 Scaffold,我将在此基础上构建视图。
谢谢
您能否为模型创建自定义数据注释,以便在 T4 模板中读取类似属性的 View。Scaffold 已读取?我想添加数据注释参数,如 Scaffold,我将在此基础上构建视图。
谢谢
我写了一篇关于我为 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;
}
}
}
所以,这就是你的做法。按照本教程了解如何创建自定义属性http://origin1tech.wordpress.com/2011/07/20/mvc-data-annotations-and-custom-attributes/
要在 T4 脚手架模板中读取此属性值,请首先按照此处所述添加模板文件http://www.hanselman.com/blog/ModifyingTheDefaultCodeGenerationscaffoldingTemplatesInASPNETMVC.aspx
然后,例如,从 AddView 文件夹中打开 List.tt。此模板创建索引视图。
转到模板文件的末尾并找到类 ModelProperty 的定义。将您的属性值添加到它( public string MyAttributeValue { get; set; }
现在在 List.tt 中往下走一点,找到 bool Scaffold(PropertyInfo property) 方法。您将需要添加自己的属性属性阅读器。对于上述教程,此方法将是:
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;
}
然后在文件底部找到方法List GetEligibleProperties(Type type)。像这样将您的阅读器添加到其中:
...
IsForeignKey = IsForeignKey(prop),
IsReadOnly = prop.GetSetMethod() == null,
Scaffold = Scaffold(prop),
MyAttributeValue = OptionalAttributesValueReader(prop)
当您想使用和阅读此属性时,您可以像在 List.tt 中使用 Scaffold 属性一样进行操作
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" #>
如果你的模型发生了变化,你需要在脚手架中找到这些新的变化,你需要重新构建你的项目。
希望任何寻找解决方案的人都会发现这很有用。请问有什么不清楚的地方。
这就是我在 MVC 5 中的做法。我很久以前就这样做了,我可能会忘记一些东西,我只是复制/粘贴我在修改后的模板中看到的内容。
我需要一种方法来设置(例如)创建/编辑视图或列表视图表中的属性顺序。所以我创建了一个OrderAttribute
带有整数属性的自定义属性Order
。
为了在 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;
}
最后,例如在 List 模板中,我添加了一个调用该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 对象。不理想,也许你可以通过其他方式得到它,但如果没有这个字符串,包括所有版本的东西,我就无法管理它。