每次使用“添加视图”或“添加控制器”功能时,您都在 ASP.NET MVC 项目中使用 T4 模板。这些模板位于 Common7\IDE\ItemTemplates\CSharp\Web\MVC 2\CodeTemplates 文件夹的 Visual Studio 安装中。另外还提供了模板的 Visual Basic 版本,但是我将其作为读者推断文件夹名称的一个练习。

这些模板本身足以说明 T4 的价值和功能。例如,以下是 CodeTemplates 的 AddView 子文件夹中 List.tt 的一段摘录:

if(!String.IsNullOrEmpty(mvcViewDataTypeGenericString)) {
Dictionary<string, string> properties =
new Dictionary<string, string>();
FilterProperties(mvcHost.ViewDataType, properties);
#>
<table>
<tr>
<th></th>http://util.cnblogs.com/InsertCode.aspx
<#
foreach(KeyValuePair<string, string> property in properties) {
#>
<th>
<#= property.Key #>
</th>
<#
}
#>

  

List.tt 的工作是生成将以表格形式显示模型对象集合的 .aspx 文件。在该模板中,您可以看到编写的表、tr 和 th 标记。若要生成 .aspx 文件,该模板需要一些上下文信息,例如,应使用的母版页的名称和模型的类型。该模板可以从其宿主对象检索此信息。该宿主对象位于模板和 T4 引擎之间,并可以使模板访问资源(如本地文件)和环境设置。通常,宿主是 Visual Studio,但 MVC 团队在 Microsoft.VisualStudio.Web.Extensions 程序集中创建了类型为 MvcTextTemplateHost 的自定义宿主。这便是沿用了您在“添加视图”和“添加控制器”对话框中输入的信息的自定义宿主对象,这些对话框是您将发现的最接近 MVC 项目中的向导的事物。

List.tt 将遍历强类型化模型对象的可显示属性并创建具有每个属性列的表。该模板使用反射在 FilterProperties 方法中查找该模型的可用属性。FilterProperties 是稍后在模板文件中定义的帮助器方法。该模板还设置了导航到编辑和详细信息操作的链接,并根据您正在创建视图还是部分视图来为 .aspx 设置适当的 @ Page 或 @ Control 指令。

当模板结束运行时,您将看到一个崭新的 .aspx 视图,该视图包含显示模型对象集合所需的所有内容。您可能会打开 .aspx 文件并进行微调以使该视图在外观上与应用程序其余部分中的视图保持一致。

如果您发现总是对这些生成的视图(或 Controller.tt 生成的控制器代码)进行相同的更改,则可以通过修改模板本身来节省时间。例如,您可以修改内置模板,以便为项目中使用的样式规则甚至更重要的内容添加类属性。请记住,修改 Visual Studio 安装目录中的模板文件将更改在您的计算机上进行的所有项目中生成的代码。如果您希望更改为单个项目生成的代码,您也可以这样做。

各个项目 T4 自定义

如果您想要基于各个项目的代码生成模板的自定义版本,则首先复制 Visual Studio 安装中的 CodeTemplates 文件夹,然后将其粘贴到您的 ASP.NET MVC 项目的根目录中。然而,不必将所有模板都复制到您的项目中。您可以只复制需要修改的模板。共有 6 个 MVC 代码生成模板,1 个用于添加控制器 (Controller.tt),其余 5 个用于添加视图(Create.tt、Details.tt、Edit.tt、Empty.tt、List.tt)。如果您的项目中存在模板,则该模板将覆盖 Visual Studio 安装目录中的模板。

当向 Visual Studio 解决方案中添加 .tt 文件时,IDE 会自动将该 .tt 文件分配给 TextTemplatingFileGenerator 的自定义工具设置。如果您创建了我之前所述的 Simple.tt 模板,则您已看到这种情况。但是,这不是 MVC T4 模板的适当设置。Visual Studio 的 MVC 工具将在适当的时候调用这些模板并在模板处理期间创建特殊的 MvcTextTemplateHost 对象。因此,将模板复制到您的项目中后,第二步是为各个模板文件打开“属性”窗口,然后删除“自定义工具”设置(保留该设置为空)。此时,便可以自定义您的模板了。

---------------------------------------------------------------------------------------------------------------------------

MvcTextTemplateHost 属性
请注意,并非 MvcTextTemplateHost 对象上的所有属性都适用于每个上下文。这些模板将在您调用“添加视图”和“添加控制器”上下文菜单项时得以执行。这两种操作均可使用 Namespace 属性并将其设置为适当的值。但是,MasterPage 属性在“添加视图”操作期间仅被设置为有效值并包含用户在“添加视图”对话框中为 MasterPage 名称输入的值。
---------------------------------------------------------------------------------------------------------------------------
例如,假设您不希望控制器执行索引操作。而更希望使用默认操作 List。您可以打开 CodeTemplates\AddController 文件夹中的 Controller.tt 模板,并将代码的相应区域更改为如下内容:
public class <#= mvcHost.ControllerName #> : Controller
{
// GET: /<#= mvcHost.ControllerRootName #>/ public ActionResult List()
{
return View();
}
...

  

这是一个简单的更改,但可为您和您的团队在整个大型项目生命周期内节省相当多的时间。

更进一步—T4MVC

2009 年夏天,ASP.NET 团队的 David Ebbo 创建了 T4MVC,一种 T4 模板,专用于在 ASP.NET MVC 应用程序中生成强类型化帮助器。随着时间的推移,Ebbo 已对该模板进行了完善,您现在可以从aspnet.codeplex.com/wikipage?title=T4mvc 下载该模板。

T4MVC 模板是传统的 T4 模板。将 T4MVC.tt 及其关联的设置文件 (T4MVC.settings.t4) 添加到您的项目,该项目将使用 TextTemplatingFileGenerator 自定义工具生成 C# 代码。T4MVC 将帮助您消除 MVC 应用程序中的许多奇妙的字符串文本。例如,模板将执行的一项任务是扫描项目中的 Content 和 Scripts 文件夹并生成具有静态属性的类以表示各个脚本和内容片段。

生成的代码意味着您可以呈现由带有该代码的默认 MVC 项目提供的 LogOnUserControl 部分视图:

<% Html.RenderPartial(MVC.Shared.Views.LogOnUserControl); %>
之前,您可能已使用了字符串文本:
<% Html.RenderPartial("LogOnUserControl"); %>

如果有人重命名、移动或删除 LogonUserControl,则强类型化代码将在编译视图时生成编译错误。除了对视图和部分视图的强类型化访问外,T4MVC 模板还提供了对 Content 和 Scripts 文件夹中的所有文件以及控制器和控制器操作的强类型化访问。

您可以在建立操作链接、返回查看结果,甚至在为应用程序构建路由表时使用 T4MVC 生成的类。请注意,当首次向项目中添加 T4MVC 时,您将看到在 IDE 的“错误列表”窗口中生成的一些警告。这些警告只是 T4MVC 向您介绍应用到代码的某些更改。其中大部分更改不会改变应用程序的行为;T4MVC 模板只向控制器类定义中添加某些局部关键字并使非虚拟操作方法变为虚拟方法。有关 T4MVC 的详细信息,请查看 Ebbo 的博客,网址为 blogs.msdn.com/davidebb

T4 是 Visual Studio 中非常神奇的财富,但还不是广为人知的模板。本文为您提供了在 ASP.NET MVC 项目中开始使用自定义模板所需的一切内容。希望您还能发现 T4 模板在 Web 应用程序项目之外的其他用途。您还应该在项目中试用 T4MVC 模板,因为这些模板可使您的代码更易于维护和重构。展望未来,Visual Studio 2010 中的 T4 技术将添加专用的项目模板和预编译模板,从而更趋完善。

转载 :https://msdn.microsoft.com/zh-sg/magazine/ee291528.aspx


ASP.NET MVC 中的 T4的更多相关文章

  1. 2.ASP.NET MVC 中使用Crystal Report水晶报表

    上一篇,介绍了怎么导出Excel文件,这篇文章介绍在ASP.NET MVC中使用水晶报表. 项目源码下载:https://github.com/caofangsheng93/CrystalReport ...

  2. 关于 ASP.NET MVC 中的视图生成

    在 ASP.NET MVC 中,我们将前端的呈现划分为三个独立的部分来实现,Controller 用来控制用户的操作,View 用来控制呈现的内容,Model 用来表示处理的数据. 从控制器到视图 通 ...

  3. 在Asp.Net MVC 中配置 Serilog

    Serilog 是一种非常简便记录log 的处理方式,使用Serilog可以生成本地的text文件, 也可以通过 Seq 来在Web界面中查看具体的log内容. 接下来就简单的介绍一下在Asp.Net ...

  4. 如何在 ASP.NET MVC 中集成 AngularJS(3)

    今天来为大家介绍如何在 ASP.NET MVC 中集成 AngularJS 的最后一部分内容. 调试路由表 - HTML 缓存清除 就在我以为示例应用程序完成之后,我意识到,我必须提供两个版本的路由表 ...

  5. 如何在 ASP.NET MVC 中集成 AngularJS(2)

    在如何在 ASP.NET MVC 中集成 AngularJS(1)中,我们介绍了 ASP.NET MVC 捆绑和压缩.应用程序版本自动刷新和工程构建等内容. 下面介绍如何在 ASP.NET MVC 中 ...

  6. 《Entity Framework 6 Recipes》中文翻译系列 (20) -----第四章 ASP.NET MVC中使用实体框架之在MVC中构建一个CRUD示例

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第四章  ASP.NET MVC中使用实体框架 ASP.NET是一个免费的Web框架 ...

  7. asp.net mvc 中 一种简单的 URL 重写

    asp.net mvc 中 一种简单的 URL 重写 Intro 在项目中想增加一个公告的功能,但是又不想直接用默认带的那种路由,感觉好low逼,想弄成那种伪静态化的路由 (别问我为什么不直接静态化, ...

  8. 在 ASP.NET MVC 中充分利用 WebGrid (microsoft 官方示例)

    在 ASP.NET MVC 中充分利用 WebGrid https://msdn.microsoft.com/zh-cn/magazine/hh288075.aspx Stuart Leeks 下载代 ...

  9. ASP.NET MVC中的两个Action之间值的传递--TempData

    一. ASP.NET MVC中的TempData 在ASP.NET MVC框架的ControllerBase中存在一个叫做TempData的Property,它的类型为TempDataDictiona ...

随机推荐

  1. extend vg(pv,lv)use HotPlug Storage PV for VMI(ECC Env)

    Preface: 前期存储未规划好,业务快速扩展,数据高安全需求(异地,More one copy),需求多多?NM干着干着活就会时不时的坑爹起来了!particularly Real Product ...

  2. sublime text 插件开发

    前言:术语和参考资料 sublime text 2的扩展模式相当的丰富.有多种方法可以修改语法高亮模式以及所有的菜单等.它还可以创建一个新的build系统,自动补全,语言定义,代码片段,宏定义,快捷键 ...

  3. 编写可维护的JS 04

    4.变量.函数和运算符 变量 变量声明提前,单var 函数声明 先声明fn再执行 函数声明不应出现在语句块中 函数调用间隔 函数名与左括号间无间隔 立即调用函数 (fuction(){}) 严格模式  ...

  4. 指定hive输出格式

    0.11版本以前: sed -e 's/\x01/|/g' file 0.11版本以后: insert overwrite local directory '/opt/aimcpro/libc/tes ...

  5. c++ 学习备忘

    char* 到 LPCTSTR 转换 char *m_str = "test!"; MessageBoxW(CString(m_str)); CString to LPCTSTR ...

  6. JDK源码学习--String篇(二) 关于String采用final修饰的思考

    JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JD ...

  7. 使用泛型对java数组扩容

    编写一个通用方法,其功能是将数组扩展到10%+10个元素(转载请注明出处) package cn.reflection; import java.lang.reflect.Array; public ...

  8. Svn入门

    1.建立svn仓库 ›    命令svnadmin create 仓库名称,如:进入命令行窗口,切换到Svn安装目录下,输入如下命令:svnadmin create F:\software\repos ...

  9. 纯JS URL编解码

    function urlEncode(str) { var ret = ""; var strSpecial = "!\"#$%&’()*+,/:;&l ...

  10. 【Android】Handler的应用(一):从服务器端加载JSON数据

    最终目的 以JSON的形式,将数据存入服务器端. 在Android中,以Handler加载显示大批量文字. 在此以加载金庸小说<天龙八部(新修版)>为例(2580480 字节). 以tom ...