【问题标题】:T4 Template and Server.MapPathT4 模板和 Server.MapPath
【发布时间】:2010-01-12 08:33:01
【问题描述】:

我正在尝试使用 T4 模板获取 Views 文件夹中的文件夹名称,但它不断给我以下错误:

错误 3 编译转换:名称“服务器”在当前上下文中不存在 c:\Projects\LearningASPMVC\LearningASPMVCSolution\LearningMVC\StronglyTypedViews.tt 20 47
错误 4 命名空间不直接包含字段或方法等成员 C:\Projects\LearningASPMVC\LearningASPMVCSolution\LearningMVC\StronglyTypedViews.cs 1 1 LearningMVC

这是 T4 模板:

<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ output extension=".cs" #>

<#@ assembly name="System.Web" #>

<#@ import namespace="System.IO" #>
<#@ import namespace="System.Web" #>


using System; 



namespace StronglyTypedViews 
{

    <# 

     string[] folders = Directory.GetDirectories(Server.MapPath("Views")); 

     foreach(string folderName in folders) 
     {

     #>  

     public static class <#= folderName #> { } 


     <# } #>        

}

更新:使用物理路径让它工作:

<#@ template language="C#" debug="True" hostspecific="True" #>
<#@ output extension=".cs" #>

<#@ assembly name="System.Web" #>
<#@ assembly name="System.Web.Mvc" #>


<#@ import namespace="System.Web.Mvc" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Web" #>


using System; 

namespace StronglyTypedViews 
{

    <# 

     string viewsFolderPath = @"C:\Projects\LearningASPMVC\LearningASPMVCSolution\LearningMVC\"; 

     string[] folders = Directory.GetDirectories(viewsFolderPath + "Views");


     foreach(string folderName in folders) 
     {

     #> 

     public static class <#= System.IO.Path.GetFileName(folderName) #> {         
     <#      
      foreach(string file in Directory.GetFiles(folderName))      {
         #>          
         public const string <#= System.IO.Path.GetFileNameWithoutExtension(file) #> = "<#= System.IO.Path.GetFileNameWithoutExtension(file).ToString()  #>";

     <# } #>



     <#  } #>

     }




}

【问题讨论】:

  • 问题是HttpContext.Current为null!

标签: t4


【解决方案1】:

T4 模板在 Visual Studio 创建的临时上下文中执行,并且完全在您的 Web 应用程序之外。该临时上下文用于生成输出文本文件。无论如何,它都不是 Web 应用程序,并且与您正在创作的 Web 应用程序无关。结果,System.Web.HttpContext 没有赋值,MapPath() 不能被调用。

Environment.CurrentDirectory 也没有多大帮助,因为模板是在某个临时文件夹中执行的。

你能做什么?如果您可以使用绝对路径,请继续这样做。否则,在 指令中添加 hostspecific 属性将允许您使用 Host 变量及其ResolvePath() 方法. ResolvePath 让您解析相对于 TT 文件本身的路径。

例如(example.tt):

<#@ template language="C#" hostspecific="True" #>
<#@ output extension=".cs" #>
// <#=Host.ResolvePath(".")#>

输出(example.cs):

// C:\Users\myusername\Documents\Visual Studio 2008\Projects\MvcApplication1\MvcApplication1\.

Oleg Sych's post about the template directive 有一个关于主机特定属性的部分。

【讨论】: