T4模板以List为参数时无表格输出、自定义类型编译报错问题
T4模板自定义List参数不生效的排查与修复
问题根因
T4模板拥有独立的编译、运行上下文,和宿主程序的程序集引用、类型作用域不共享:
- 传入的
Cnt是System.Int32类型,属于基础库内置类型,T4默认就引用了mscorlib程序集,因此可以正常识别、传值、渲染 - 自定义的
SiteStat类型定义在你项目自身的ScheduledJobsService程序集中,模板既没有显式引用这个程序集,也没有导入对应命名空间:- 一方面会导致参数类型识别失败,引擎可能静默将传入的集合置空,最终foreach遍历不到任何内容,table里自然没有生成任何行
- 另一方面哪怕你写全限定名声明参数类型,由于模板根本没有加载包含该类型的程序集,编译阶段就会直接报错“命名空间下不存在SiteStat类型”
可落地修复步骤
- 添加assembly程序集引用指令
在模板顶部新增该指令,指向编译生成的、包含SiteStat类型的程序集,推荐用VS内置路径宏匹配项目输出路径,避免硬写绝对路径:<#@ assembly name="$(ProjectDir)bin\Debug\你的目标框架版本\ScheduledJobsService.dll" #>注意:必须引用编译后的dll文件,T4模板不会直接解析你的C#源码文件
- 添加import命名空间导入指令
在模板顶部新增该指令,导入SiteStat所在的命名空间,后续写代码就不需要反复写全限定名:<#@ import namespace="ScheduledJobsService" #> - 验证参数类型匹配
完成上面两步配置后,模板原本的参数声明List<SiteStat>就可以被正常编译识别,不需要刻意修改为全限定名写法。 - 传入值校验
传参时确认Stats参数传入的不是null,且集合内的元素类型确实是SiteStat——很多时候遍历无输出是因为传入的集合本身为空,和模板逻辑无关。
常见踩坑提醒
- 如果是在运行时(比如你的定时任务服务内)调用T4文本转换引擎,需要在引擎初始化阶段,手动将包含
SiteStat的程序集加载到当前AppDomain,否则模板运行时依然会抛出类型找不到的异常 - 遇到无输出的情况优先查看T4转换的错误日志,很多时候类型加载失败的异常会被引擎静默吞掉,不会直接弹窗提示
- 不要硬写程序集的绝对路径,否则换开发设备、调整项目目录结构后,模板会直接失效
内容的提问来源于stack exchange,提问作者Tommie Jones
相关产品推荐
相关产品推荐

