【发布时间】:2014-01-28 19:12:35
【问题描述】:
我正在尝试访问我正在编写的 T4 控制器模板中附加到我的模型属性的 SortableAttribute 等自定义属性。我已经从 List.tt 复制了类块、程序集和导入作为样板。
首先我尝试按如下方式转换属性:
<#+
string SortableBy(PropertyInfo property)
{
foreach (object attribute in property.GetCustomAttributes(true))
{
var sortable = attribute as SortableAttribute;
if (sortable != null) return sortable.By == "" ? property.Name : sortable.By;
}
return property.Name;
}
#>
然而,这并没有产生积极的结果,因为我的项目的命名空间对于 T4 是未知的。为了解决这个问题,我添加了项目的 dll 并导入了所需的命名空间。
<#@ assembly name ="c:\path\to\MyProject\bin\MyProject.dll" #>
<#@ import namespace= "MyProject.Filters" #>
一开始似乎是成功的(例如,命名空间导入没有错误),但它仍然没有找到我的属性。如果我将SortableAttribute 替换为MyProject.Filters.SortableAttribute,则错误消息是在MyProject.Filters 中找不到SortableAttribute。
为了克服这个问题,我将代码更改如下:
<#+
string SortableBy(PropertyInfo property)
{
foreach (object attribute in property.GetCustomAttributes(true))
{
if (attribute != null && attribute.GetType().Name == "SortableAttribute")
{
var sortableBy = (string) attribute.GetType().GetProperty("By").GetValue(attribute, null);
return sortableBy == "" ? property.Name : sortableBy;
}
}
return property.Name;
}
#>
我以为我中了大奖,但我很快就意识到property.GetCustomAttributes(true) 返回所有属性但不是我的...
一个示例模型:
public class MyModel
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
[Display(Name = "Full Name")]
[Sortable]
public int Name { get; set; }
}
SortableAttribute的实现:
using System;
namespace MyProject.Filters
{
[AttributeUsage(AttributeTargets.Property)]
public class SortableAttribute : Attribute
{
public SortableAttribute(string by = "")
{
this.By = by;
}
public string By { get; private set; }
}
}
你能告诉我正确的方向吗?
非常感谢任何帮助!
编辑:
事实证明,property.GetCustomAttributes(true) 确实返回了我的属性,但 SortableBy 中的以下表达式始终计算为 null:
(string) attribute.GetType().GetProperty("By").GetValue(attribute, null);
知道为什么会这样吗?
【问题讨论】:
-
显示您从对象中获取属性的 T4 代码。我的猜测是你没有检查你认为的属性。
-
我正在检查正确的属性,因为我得到的属性名称是正确的。请查看我更新的问题。
标签: c# asp.net-mvc-4 reflection data-annotations t4