访问T4模板中的自定义属性(VS2012 MVC4)

时间:2014-01-28 19:12:36

标签: c# asp.net-mvc-4 reflection data-annotations t4

我正在尝试在我正在编写的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,则错误消息是SortableAttribute中未找到MyProject.Filters

为了解决这个问题,我改变了我的代码如下:

<#+
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);

知道为什么会这样吗?

2 个答案:

答案 0 :(得分:2)

请记住:Build修复了很多问题,但 REBUILD 可以解决所有问题!

回顾一下并帮助其他人编写T4模板,这里有一些可用作样板的工作代码:

在.tt文件中读取自定义属性(基于任何默认视图模板中的Scaffold()):

<#+
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;
}
#>

型号:

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; }
    }
}

答案 1 :(得分:0)