You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在.NET 6的T4模板中使用DisplayAttribute编译报错,如何解决?

在.NET 6 T4模板中读取DisplayAttribute的报错解决

问题场景

在.NET 6项目(Visual Studio 2022 17.0.4版本)的自定义T4模板中,尝试读取枚举成员的DisplayAttribute时,编译模板出现类型找不到的错误,提示该类型已转发到旧版本的程序集。

原T4代码片段

<#@ template debug="true" hostspecific="true" language="C#" compilerOptions="/langversion:10" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Runtime" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.ComponentModel.Annotations" #>

<#@ import namespace="System" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Runtime" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.ComponentModel.DataAnnotations" #> 
<#@ output extension=".cs" #>

<#
    static string GetEnumValueDisplayName(Enum value)
    {
        Type type = value.GetType();
        MemberInfo[] memInfo = type.GetMember(value.ToString());
        DisplayAttribute? dispalyAttribute = null;
        if (memInfo != null && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DisplayAttribute), false);

            if (attrs != null && attrs.Length > 0)
                dispalyAttribute = attrs[0] as DisplayAttribute;
        }
        return dispalyAttribute?.Name ?? "";
    }
#>

<#
 foreach(myEnum en in Enum.GetValues(typeof(MyEnum)))
 {#>
          public static class <#=@en.ToString()#> { public const string Value = "<#=@en.ToString()#>";public const string Text = "<#=@GetEnumValueDisplayName(en)#>";}
<#}#>

报错信息

Compiling transformation: The type name 'DisplayAttribute' could not be found in the namespace 'System.ComponentModel.DataAnnotations'. This type has been forwarded to assembly 'System.ComponentModel.Annotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' Consider adding a reference to that assembly.

解决方案

1. 指定正确的程序集强名称引用

.NET 6中System.ComponentModel.Annotations的强名称版本为6.0.0.0,替换原有的程序集引用语句:

// 替换原有的<#@ assembly name="System.ComponentModel.Annotations" #>
<#@ assembly name="System.ComponentModel.Annotations, Version=6.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" #>

2. 使用项目本地NuGet包路径引用(可选)

如果项目已安装该NuGet包,可直接引用本地包中的程序集路径(注意替换版本号为你项目中使用的版本):

<#@ assembly name="$(SolutionDir)packages\System.ComponentModel.Annotations.6.0.0\lib\net6.0\System.ComponentModel.Annotations.dll" #>

3. 优化获取DisplayAttribute的方法

可以用LINQ简化原方法,同时避免空引用检查的冗余代码:

static string GetEnumValueDisplayName(Enum value)
{
    return value.GetType()
                .GetMember(value.ToString())
                .FirstOrDefault()?
                .GetCustomAttribute<DisplayAttribute>()?
                .Name ?? string.Empty;
}

注意事项

  • 确保项目中已安装System.ComponentModel.Annotations NuGet包(.NET 6控制台/类库项目可能需要手动安装)。
  • 若使用强名称引用,需保证版本号与项目依赖的版本完全一致。
  • 修改T4模板后,可尝试重启Visual Studio或重新生成项目,确保模板编译生效。

内容的提问来源于stack exchange,提问作者theGhostN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 21:01:36