{"id":3884,"date":"2009-01-29T18:12:00","date_gmt":"2009-01-29T18:12:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/webdev\/2009\/01\/29\/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers\/"},"modified":"2009-01-29T18:12:00","modified_gmt":"2009-01-29T18:12:00","slug":"t4-templates-a-quick-start-guide-for-asp-net-mvc-developers","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/t4-templates-a-quick-start-guide-for-asp-net-mvc-developers\/","title":{"rendered":"T4 Templates: A Quick-Start Guide for ASP.NET MVC Developers"},"content":{"rendered":"<p><P>As mentioned in our <a href=\"http:\/\/blogs.msdn.com\/webdevtools\/archive\/2009\/01\/27\/overview-of-mvc-tools-features.aspx\" target=\"_blank\" rel=\"noopener\">recent blog post<\/A> on the <a href=\"http:\/\/go.microsoft.com\/fwlink\/?LinkID=141184&amp;clcid=0x409\" target=\"_blank\" rel=\"noopener\">ASP.NET MVC Release Candidate<\/A>, our code-generation features (namely, Add Controller and Add View) now use the T4 (Text Template Transformation Toolkit) templating technology behind the scenes.&nbsp; Because users can customize the templates to a great extent, we wanted to make a post to bring everyone up to speed on T4.<\/P>\n<H4>Template Locations and Template Override<\/H4>\n<P>The Add Controller and Add View dialogs both perform code generation that use T4 templates behind the scenes.&nbsp; These templates can be modified to customize the generated code from these tools.&nbsp; You can find the templates at the following location: [Visual Studio Install Directory]\\Common7\\IDE\\ItemTemplates\\[CSharp | VisualBasic]\\Web\\MVC\\CodeTemplates\\<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/TemplatesLocation_4.jpg\"><IMG title=\"TemplatesLocation\" height=\"239\" alt=\"TemplatesLocation\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/TemplatesLocation_thumb_1.jpg\" width=\"957\" border=\"0\"><\/A> <\/P>\n<P>You can also copy the \u2018CodeTemplates\u2019 folder into the root of your project to be able to override the templates at the above location and customize the templates on a per-project basis (alternatively, just create a folder named \u2018CodeTemplates\u2019 and under that create a folder named \u2018AddController\u2019 or \u2018AddView\u2019).&nbsp; Note that you can choose to override some templates but not others if you so wish \u2013 the dialogs will respect the precedence of what is in your project properly.&nbsp; Also keep in mind that for the Add View dialog, you can add your own .tt files either at the global location or in your project and have them automatically populated in the View Content drop-down in the dialog.<\/P>\n<P>Please note that when you copy the above folder (really, any time you add a .tt file) into the project, you will see warnings as follows:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/TemplateExecutionWarning_2.jpg\"><IMG title=\"TemplateExecutionWarning\" height=\"202\" alt=\"TemplateExecutionWarning\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/TemplateExecutionWarning_thumb.jpg\" width=\"553\" border=\"0\"><\/A> <\/P>\n<P>Hit \u2018Cancel\u2019 so that you don\u2019t run the T4 template (if you are adding multiple .tt files like when you copy the \u2018CodeTemplates\u2019 folder, you will have to hit \u2018Cancel\u2019 each time).&nbsp; This happens because as soon as the project sees a .tt file, a property on the file called \u2018CustomTool\u2019 will get set to \u2018TextTemplatingFileGenerator\u2019&nbsp; What this is telling Visual Studio to do is to use the default T4 host to execute the template and create a new file (nested underneath the template) based on what\u2019s in the template.<\/P>\n<P>The generator can be a great way to have one-off file generation based on a template, or to simply play around with T4 \u2013 however, because Add View and Add Controller templates have code in them that rely on a custom template host (as you\u2019ll see later), executing these templates with the default generator will simply generate errors.&nbsp; Go ahead and clear out the Custom Tool property to just be empty after copying the templates into your project.<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CustomToolProperty_2.jpg\"><IMG title=\"CustomToolProperty\" height=\"195\" alt=\"CustomToolProperty\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CustomToolProperty_thumb.jpg\" width=\"357\" border=\"0\"><\/A>&nbsp;<\/P>\n<P><EM>Note: If you want to get rid of the mapping that automatically sets the Custom Tool on .tt files, you can do so through the registry \u2013 please note that if you want to restore these registry keys to their default values, you can perform a Repair from the Visual Studio installer, or add the entries back manually.&nbsp; Start up the registry editor (Start \u2013&gt; Run \u2013&gt; \u2018regedit\u2019) and navigate to one of the following locations depending on whether you are using a 32-bit or 64-bit install of Windows:<\/EM><\/P>\n<P><EM>32-bit: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\Generators<\/EM><\/P>\n<P><EM>64-bit: HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\Generators<\/EM><\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4Registry_2.jpg\"><EM><IMG title=\"T4Registry\" height=\"527\" alt=\"T4Registry\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4Registry_thumb.jpg\" width=\"360\" border=\"0\"><\/EM><\/A><EM> <\/EM><\/P>\n<P><EM>Expand each of the nodes directly under \u2018Generators\u2019 and look for any entries named \u2018.tt\u2019.&nbsp; Set the registry value named \u2018(Default)\u2019 to be empty.&nbsp; That\u2019s it!<\/EM><\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4RegistryEdit_2.jpg\"><IMG title=\"T4RegistryEdit\" height=\"240\" alt=\"T4RegistryEdit\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4RegistryEdit_thumb.jpg\" width=\"439\" border=\"0\"><\/A> <\/P>\n<P>If you want to override the global templates but don\u2019t want to copy a folder named \u2018CodeTemplates\u2019 into your project (since you already have a folder by that name presumably), you can change the name of the folder Add Controller and Add View look at through a registry key.&nbsp; Start up the registry editor (Start \u2013&gt; Run \u2013&gt; \u2018regedit\u2019) and navigate to one of the following locations depending on whether you are using a 32-bit or 64-bit install of Windows:<\/P>\n<P>32-bit: HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\9.0\\MVC\\CodeTemplates<\/P>\n<P>64-bit: HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\9.0\\MVC\\CodeTemplates<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4OverrideRegistry_2.jpg\"><IMG title=\"T4OverrideRegistry\" height=\"75\" alt=\"T4OverrideRegistry\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4OverrideRegistry_thumb.jpg\" width=\"223\" border=\"0\"><\/A> <\/P>\n<P>Change the value for \u2018OverrideDir\u2019 to what you want the tooling to look for in your project.&nbsp; Please note that under this folder you will still have to maintain the same hierarchy as before, with a folder named \u2018AddController\u2019 and\/or a folder named \u2018AddView\u2019.<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4OverrideRegistryEdit_2.jpg\"><IMG title=\"T4OverrideRegistryEdit\" height=\"261\" alt=\"T4OverrideRegistryEdit\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4OverrideRegistryEdit_thumb.jpg\" width=\"429\" border=\"0\"><\/A><\/P>\n<H4>Editing T4 Templates<\/H4>\n<P>If you open a .tt file inside Visual Studio, you may notice they look a bit flat \u2013 like a wall of black text.&nbsp; We highly highly recommend you download <a href=\"http:\/\/www.t4editor.net\/\" target=\"_blank\" rel=\"noopener\">T4 Editor<\/A>, an add-on to Visual Studio made by <a href=\"http:\/\/www.clariusconsulting.net\/\" target=\"_blank\" rel=\"noopener\">Clarius Consulting<\/A>, to provide you with syntax highlighting and some basic T4 statement completion.&nbsp; They have a free version called the \u2018Community Edition\u2019, as well as a much more powerful \u2018Professional Edition\u2019 \u2013 check out the <a href=\"http:\/\/www.t4editor.net\/features.html\" target=\"_blank\" rel=\"noopener\">feature comparison<\/A> if you are interested.&nbsp; This add-on really makes a big difference in template authoring, as you can see below.<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4EditingWithoutClarius_2.jpg\"><IMG title=\"T4EditingWithoutClarius\" height=\"353\" alt=\"T4EditingWithoutClarius\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4EditingWithoutClarius_thumb.jpg\" width=\"492\" border=\"0\"><\/A> <A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4EditingWithClarius_2.jpg\"><IMG title=\"T4EditingWithClarius\" height=\"337\" alt=\"T4EditingWithClarius\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/T4EditingWithClarius_thumb.jpg\" width=\"449\" border=\"0\"><\/A> <\/P>\n<H4>Anatomy of a T4 Template<\/H4>\n<P>The easiest way to get started with editing the templates yourself is to see how our default templates work.&nbsp; To that end, we\u2019re going to go through some of the pieces of the \u2018Create\u2019 template (Create.tt) for Add View.&nbsp; Let\u2019s start at the top:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate1_4.jpg\"><IMG title=\"CreateTemplate1\" height=\"74\" alt=\"CreateTemplate1\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate1_thumb_1.jpg\" width=\"458\" border=\"0\"><\/A> <\/P>\n<P>These four lines are all <EM>directives<\/EM>.<\/P>\n<OL>\n<LI>The first line is the <EM>template directive<\/EM>, and its main job is to tell the T4 engine what language the template itself uses.&nbsp; When we say the template\u2019s language, we don\u2019t mean the language in which the output is written, but rather the template\u2019s control code (for example, your template might include an <EM>if-else<\/EM> statement to conditionally output some line of text).&nbsp; The \u2018HostSpecific\u2019 attribute has to be set to \u2018True\u2019 to work with Add View or Add Controller, because otherwise the template cannot access the information the Add Controller and Add View dialogs want to provide them (things like the Type to which a strongly-typed view is bound etc) <\/LI>\n<LI>The next line is the <EM>output directive<\/EM>, and it simply sets the default extension for the template\u2019s output file by informing the template host \u2013 this isn\u2019t particularly relevant to MVC Tools since depending on the situation the default extension may be ignored (for example, if we are dealing with a partial view, where the extension should be .ascx) <\/LI>\n<LI>The next couple lines are both <EM>import directives<\/EM>, and they are like \u2018using\u2019 statements in C# or \u2018Imports\u2019 statements in VB.&nbsp; If your template\u2019s code uses any classes in its code, you will need to import them here.<\/LI><\/OL>\n<P>You can find more documentation on T4 directives here: <a title=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126421.aspx\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126421.aspx\" target=\"_blank\" rel=\"noopener\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb126421.aspx<\/A><\/P>\n<P>Moving down just a bit, you will notice the following line:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate2_2.jpg\"><IMG title=\"CreateTemplate2\" height=\"24\" alt=\"CreateTemplate2\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate2_thumb.jpg\" width=\"509\" border=\"0\"><\/A> <\/P>\n<P>On this line we are creating a new variable named \u2018mvcHost\u2019, and assigning it to a casted version of a property named \u2018Host\u2019.&nbsp; The \u2018Host\u2019 property is something provided to the template automatically because we set the \u2018HostSpecific\u2019 attribute to \u2018True\u2019 in the template directive above.&nbsp; The MVC Tools provide a custom host, so as to be able to pass information to the templates that are not available outside of the tools.&nbsp; To access the properties provided on our host class, the \u2018Host\u2019 property needs to be casted to our host type, which is \u2018MvcTextTemplateHost\u2019.<\/P>\n<P>How is this variable used?&nbsp; It is actually quite straightforward:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate3_2.jpg\"><IMG title=\"CreateTemplate3\" height=\"212\" alt=\"CreateTemplate3\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate3_thumb.jpg\" width=\"419\" border=\"0\"><\/A>&nbsp;<\/P>\n<P>The first thing to notice is that there is code enclosed within \u2018&lt;#\u2019 and \u2018#&gt;\u2019 tags.&nbsp; These tags are called <EM>statement blocks<\/EM> and are used to enclose control code.&nbsp; Your template may want to conditionally output certain chunks of text into the output file and keep other chunks from being outputted.&nbsp; Above, we have an <EM>if<\/EM> statement (written in C# since our template\u2019s language was set to C# in the template directive) that opens a curly brace.&nbsp; This <EM>if<\/EM> statement\u2019s closing curly brace shows up a few lines below on Line 17, in a different statement block.&nbsp; Note that this particular <EM>if<\/EM> statement is accessing a property on the host called \u2018IsViewUserControl\u2019, which tells the template if the user chose to go with a partial view.<\/P>\n<P>All the text outside of blocks in a template are actual chunks of text that are outputted to the final file.&nbsp; In the screenshot above, Line 14\u2019s text is outside of any blocks and is thus part of the output \u2013 however, it will be placed into the output file only if the <EM>if<\/EM> statement on Line 12 evaluates to \u2018true\u2019.<\/P>\n<P>You can learn more about T4 statement blocks here: <a title=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126509.aspx\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126509.aspx\" target=\"_blank\" rel=\"noopener\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb126509.aspx<\/A><\/P>\n<P>The easiest way to think of the control code in a T4 template is by sewing it together in your head into one big program.&nbsp; The variable we declared previously on line 6 can be used in the T4 control code that follows it \u2013 and each of these if-else branches conditionally adds some text (shown in gray) to the outputted file.&nbsp; The if-else statements above are checking some properties exposed by our template host to the Add View templates.<\/P>\n<P>Moving a bit further down, we see a curious statement block as follows:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate4_4.jpg\"><IMG title=\"CreateTemplate4\" height=\"90\" alt=\"CreateTemplate4\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate4_thumb_1.jpg\" width=\"544\" border=\"0\"><\/A> <\/P>\n<P>We declare a variable called \u2018properties\u2019 of type \u2018List&lt;string&gt;\u2019.&nbsp; How are we able to use the List type in our T4 code?&nbsp; It is because of this import directive we saw at the top of the template:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate5_2.jpg\"><IMG title=\"CreateTemplate5\" height=\"23\" alt=\"CreateTemplate5\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate5_thumb.jpg\" width=\"458\" border=\"0\"><\/A> <\/P>\n<P>Line 56 then calls a method called \u2018FilterProperties\u2019 \u2013 but where is this method located?&nbsp; It is actually defined near the bottom of the template:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate6_2.jpg\"><IMG title=\"CreateTemplate6\" height=\"243\" alt=\"CreateTemplate6\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate6_thumb.jpg\" width=\"1072\" border=\"0\"><\/A> <\/P>\n<P>If you look carefully, unlike statement blocks, this block of code begins with \u2018&lt;#+\u2019.&nbsp; This is known as a <EM>class feature blocks<\/EM>, and they work like this: T4 takes all the class features in your template and adds them to the class that is compiled from your template behind the scenes.&nbsp; This isn\u2019t just limited to methods, but also things like properties (anything that would normally go under a class).&nbsp; Like a member of a class in a regular code file, these now become accessible to the rest of your template\u2019s code.<\/P>\n<P>Read more about class feature blocks here: <a title=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126541.aspx\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126541.aspx\" target=\"_blank\" rel=\"noopener\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb126541.aspx<\/A><\/P>\n<P>Our default templates use the \u2018FilterProperties\u2019 method from the above screenshot to by default output markup only for some properties in the type \u2013 namely ones that are public and would also be displayed in the designer by things like GridView.&nbsp; This logic is identical to what you would get from calling the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.web.ui.webcontrols.gridview.isbindabletype.aspx\" target=\"_blank\" rel=\"noopener\">GridView.IsBindableType<\/A> method.<\/P>\n<P>The \u2018IsBindableType\u2019 method called on Line 136 is defined a bit further down in the template:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate7_2.jpg\"><IMG title=\"CreateTemplate7\" height=\"333\" alt=\"CreateTemplate7\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate7_thumb.jpg\" width=\"1131\" border=\"0\"><\/A> <\/P>\n<P>If you wanted to change which properties our templates filter out, you can modify either of these methods to your liking.<\/P>\n<P>Lastly, have a look at Line 65 below:<\/P>\n<P><A href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate8_2.jpg\"><IMG title=\"CreateTemplate8\" height=\"163\" alt=\"CreateTemplate8\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/16\/2019\/02\/CreateTemplate8_thumb.jpg\" width=\"441\" border=\"0\"><\/A><\/P>\n<P>Here, we have a new construct that begins with \u2018&lt;#=\u2019.&nbsp; This is called an <EM>expression block<\/EM> and it is used to insert values from T4 code into the outputted text.&nbsp; As you can see above, we have a foreach loop that is iterating properties and defines a variable local to the loop called \u2018propertyName\u2019.&nbsp; Because we want to output a &lt;th&gt; tag for each property name, we use an expression block referencing that variable.<\/P>\n<P>You can find more about expression blocks here: <a title=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126508.aspx\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/bb126508.aspx\" target=\"_blank\" rel=\"noopener\">http:\/\/msdn.microsoft.com\/en-us\/library\/bb126508.aspx<\/A><\/P>\n<P>As you can see, the various ways through which you can selectively output text in a T4 template make T4 a very powerful tool in getting the productivity of automatic code-generation with the flexibility of customized output.<\/P>\n<H4>MVC Tools T4 Host Properties<\/H4>\n<P>The Add Controller and Add View dialogs each expose different properties to templates through the template host, as demonstrated above in our breakdown of the Create template.&nbsp; Here is the full list of available properties exposed by our template host, for your template to use (<EM>Note: The exact names of these properties may change between the RC and the final version<\/EM>):<\/P>\n<H5><\/H5>\n<H5>Add Controller:<\/H5>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"900\" border=\"1\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"300\">\n<P align=\"center\"><STRONG>Property Name<\/STRONG><\/P>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\"><STRONG>Type<\/STRONG><\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\"><STRONG>Description<\/STRONG><\/P><\/TD><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"300\">\n<P align=\"center\">ItemName<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">The name of the Controller class, including the \u2018Controller\u2019 suffix<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"300\">\n<P align=\"center\">NameSpace<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">The namespace into which the Controller is being generated<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"300\">\n<P align=\"center\">ExtraActionMethods<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">System.Boolean<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">Indicates whether or not the user checked the option in the Add Controller dialog to get extra action methods<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"300\">\n<P align=\"center\">ControllerRootName<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"299\">\n<P align=\"center\">The name of the controller class without the \u2018Controller\u2019 suffix<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<H5>Add View:<\/H5>\n<TABLE class=\"\" cellSpacing=\"0\" cellPadding=\"2\" width=\"898\" border=\"1\">\n<TBODY>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"298\">\n<P align=\"center\"><STRONG>Property Name<\/STRONG><\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"305\">\n<P align=\"center\"><STRONG>Type<\/STRONG><\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"293\">\n<P align=\"center\"><STRONG>Description<\/STRONG><\/STRONG><\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"296\">\n<P align=\"center\">ItemName<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"309\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"291\">\n<P align=\"center\">The name of the view (without extension), as typed in the Add View dialog<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"295\">\n<P align=\"center\">NameSpace<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"312\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"289\">\n<P align=\"center\">The default namespace of the view\u2019s parent folder<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"294\">\n<P align=\"center\">IsViewUserControl<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"315\">\n<P align=\"center\">System.Boolean<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"288\">\n<P align=\"center\">Evaluates to true if the user chose a partial view in the Add View dialog<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"293\">\n<P align=\"center\">IsViewContentPage<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"317\">\n<P align=\"center\">System.Boolean<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"287\">\n<P align=\"center\">Evaluates to true if the user is creating a view with a master page<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"292\">\n<P align=\"center\">IsViewPage<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"319\">\n<P align=\"center\">System.Boolean<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"286\">\n<P align=\"center\">Evaluates to true if the user is creating a regular view page<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"292\">\n<P align=\"center\">MasterPage<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"320\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"286\">\n<P align=\"center\">Path to the master page the user chose in the dialog (to be used only when IsViewContentPage is true)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"291\">\n<P align=\"center\">ContentPlaceholder<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"321\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"285\">\n<P align=\"center\">Name of the primary content place holder into which the generated content will be placed. This is the content place holder id the user typed into the Add View dialog<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"291\">\n<P align=\"center\">ContentPlaceHolders<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"322\">\n<P align=\"center\">System.Collections.Generic.List&lt;System.String&gt;<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"285\">\n<P align=\"center\">A list of all content place holder ID\u2019s in the master page, if a master page was chosen for this view<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"290\">\n<P align=\"center\">LanguageExtension<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"323\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"284\">\n<P align=\"center\">The output file\u2019s extension (including the period)<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"290\">\n<P align=\"center\">ViewDataTypeGenericString<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"324\">\n<P align=\"center\">System.String<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"284\">\n<P align=\"center\">This is a string that is used to output the generics clause for the \u2018Inherits\u2019 attribute in the view&#8217;s directive (for strongly-typed views).&nbsp; Example: \u201c&lt;MyType&gt;\u201d or \u201c(Of MyType)\u201d<\/P><\/TD><\/TR>\n<TR>\n<TD class=\"\" vAlign=\"top\" width=\"290\">\n<P align=\"center\">ViewDataType<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"325\">\n<P align=\"center\">System.Type<\/P><\/TD>\n<TD class=\"\" vAlign=\"top\" width=\"284\">\n<P align=\"center\">This is a Type object representing the type to which a strongly-typed view is bound. It can be used to get information on the properties in the type and the like<\/P><\/TD><\/TR><\/TBODY><\/TABLE>\n<P>Additionally, there are a few properties exposed by the default \u2018Host\u2019 property that you may find useful, such as the path to the template currently being executed.&nbsp; You can read more about those properties here: <a title=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.visualstudio.texttemplating.itexttemplatingenginehost_properties.aspx\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.visualstudio.texttemplating.itexttemplatingenginehost_properties.aspx\" target=\"_blank\" rel=\"noopener\">http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.visualstudio.texttemplating.itexttemplatingenginehost_properties.aspx<\/A><\/P>\n<H4>Summary<\/H4>\n<P>We hope this article has given you enough information about T4 templates and how to effectively use them in conjunction with the tooling Visual Web Developer provides for ASP.NET MVC.&nbsp; There is a lot more you can do with T4 than just what we went over in this post, so check out some of the information out there (<a href=\"http:\/\/www.hanselman.com\/blog\/T4TextTemplateTransformationToolkitCodeGenerationBestKeptVisualStudioSecret.aspx\" target=\"_blank\" rel=\"noopener\">Scott Hanselman\u2019s post<\/A> is a great place to start) and see what you can come up with.&nbsp; PLEASE post any comments, suggestions, or questions you have.&nbsp; Thanks for reading!<\/P>\n<P>Abhishek Mishra | Software Design Engineer | Visual Studio Web Developer<\/P><\/p>\n","protected":false},"excerpt":{"rendered":"<p>As mentioned in our recent blog post on the ASP.NET MVC Release Candidate, our code-generation features (namely, Add Controller and Add View) now use the T4 (Text Template Transformation Toolkit) templating technology behind the scenes.&nbsp; Because users can customize the templates to a great extent, we wanted to make a post to bring everyone up [&hellip;]<\/p>\n","protected":false},"author":404,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197],"tags":[4,31,7288,7262,7286,7327,7287,147,7302,7316,7319,7267],"class_list":["post-3884","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","tag-net","tag-asp-net","tag-asp-net-mvc-framework","tag-development","tag-mvc","tag-t4","tag-tdd","tag-visual-studio","tag-visual-studio-2008","tag-visual-studio-2008-sp1","tag-visual-web-developer","tag-vwd"],"acf":[],"blog_post_summary":"<p>As mentioned in our recent blog post on the ASP.NET MVC Release Candidate, our code-generation features (namely, Add Controller and Add View) now use the T4 (Text Template Transformation Toolkit) templating technology behind the scenes.&nbsp; Because users can customize the templates to a great extent, we wanted to make a post to bring everyone up [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/3884","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/404"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=3884"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/3884\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=3884"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=3884"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=3884"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}