Walkthrough: Debugging a Text Template
Before you can debug a text template, you should understand the two steps of the template transformation process. Different classes of errors can occur within each step. The steps are as follows.
The text template transformation engine creates a class that is named the generated transformation class. In order to create the generated transformation class, the text template transformation engine must be able to parse the text template.
In this step, errors in the text template such as incorrect tags might prevent it from being parsed. Errors are reported with the correct text template line number.
The engine compiles the generated transformation class.
In this step, code errors might prevent the generated transformation class from compiling. Most errors are reported with the correct text template line number. Mismatched brackets in the template code can cause errors that refer to the transformed class, which has a temporary filename.
The compiled transformation class is executed to produce the output.
Errors at this stage are not reported with a correct line number. You can step through execution of the template code, but you must launch the debugger explicitly as described in a following section.
To debug a text template, you must first correct errors in the text template. Then you must correct errors in the generated transformation class.
Note
When you transform a text template, you can get errors from any of three sources: the text template, the generated transformation class, and any directives that you call from within the text template. In this walkthrough you will debug errors in the text template and the generated transformation class. However, you can also use these procedures to debug custom directives.
Tasks illustrated in this walkthrough include the following:
Debugging an incorrect text template tag
Stepping through the template code
Creating a Text Template
Create a C# console application project and add a text template to your solution. You will debug this text template in later steps.
To create a text template
In Visual Studio, create a new C# console application and name it DebugTemplate.
Add a text template file that is named DebugTest.tt to the DebugTemplate project.
Make sure that the Custom Tool property of DebugTest.tt is set to TextTemplatingFileGenerator.
Edit the file to contain just the following line:
<#@ output extension=".txt" #>
Save the file.
The system transforms the text template and generates the corresponding output file. The new file appears in Solution Explorer under the text template file.
Debugging an Incorrect Text Template Tag
A common syntax error when you write text templates is to use an incorrect start or end tag. In this procedure, you will debug an incorrect tag.
To debug an incorrect text template tag
Add the following code to DebugTest.tt:
Note
The code contains an error. You are introducing the error on purpose to debug it.
<# for (int i = 0; i < 3; i++) { > Hello, World! <# } #>
Save the file.
The Error List window appears and displays this error:
An unexpected start or end tag was found within a block. Make sure that you did not mis-type a start or end tag, and that you do not have any nested blocks in the template.
In this case, the error in the code is an incorrect end tag. The # in the end tag is missing.
Double-click the error in the Error List window to jump to the code.
To correct the code, add the # to the end tag.
<# for (int i = 0; i < 3; i++) { #>
Save the file.
Now the system transforms the text template and generates the corresponding output file. There are no errors in the Error List window.
Stepping through the template code
To step through template code, you need to add two things to the template:
<@#template debug="true" #>
System.Diagnostics.Debugger.Launch();
In the following procedure, you will debug an element index that does not exist. This error is similar to errors from the previous procedures. However, this time you will debug it by using the Visual Studio Debugger.
To debug by using the debugger
Create a folder C:\nonsense and then save an empty text file that is named nonsense.xml to that folder
Replace the code in DebugTest.tt with the following code:
Note
The code contains an error. You are introducing the error on purpose to debug it.
<#@ output extension=".txt" #> <#@ assembly name="System.Xml.dll" #> <#@ import namespace="System.Xml" #> <# XmlDocument xDoc = new XmlDocument(); xDoc.Load(@"C:\nonsense\nonsense.xml"); XmlAttributeCollection attributes = xDoc.Attributes; if (attributes != null) { foreach (XmlAttribute attr in attributes) { #> <#= attr.Name #> <# } } #>
Save the file.
The Error List window appears and displays the following error:
Running transformation: System.Xml.XmlException: Root element is missing.
Add a template directive with the debug parameter set to true:
<#@ template debug="true" #>
Add a System.Diagnostics.Debugger.Launch() statement to the text template code.
The code will look like the following:
<#@ template debug="true" #> <#@ output extension=".txt" #> <#@ assembly name="System.Xml.dll" #> <#@ import namespace="System.Xml" #> <# XmlDocument xDoc = new XmlDocument(); System.Diagnostics.Debugger.Launch(); xDoc.Load(@"C:\nonsense\nonsense.xml"); XmlAttributeCollection attributes = xDoc.Attributes; if (attributes != null) { foreach (XmlAttribute attr in attributes) { #> <#= attr.Name #> <# } } #>
Run the transformation again.
The Visual Studio Just-In-Time Debugger dialog box appears.
In the Possible Debuggers list, click New instance of Visual Studio 2010, and then click Yes.
DebugTest.tt opens in a new instance of Visual Studio.
Step through the code to the line:
xDoc.Load(@"C:\nonsense\nonsense.xml");
The error will be raised at this line.
Close the second instance of Visual Studio.
On the Debug menu, click Stop Debugging.
On the File menu, click Exit.
When you are prompted to save changes to the solution, click No.
The second instance of Visual Studio closes.
Fix the text template and remove the debugging features.
In Solution Explorer, double-click DebugTest.tt to open it in the editor.
Fix the incorrect file name. For example, replace it with:
@"C:\\Program Files\\Microsoft Visual Studio 10.0\\Xml\\SnippetsIndex.xml"
Remove the template directive and the break line.
The text template should look like this:
<#@ output extension=".txt" #> <#@ assembly name="System.Xml.dll" #> <#@ import namespace="System.Xml" #> <# XmlDocument xDoc = new XmlDocument(); xDoc.Load(@"C:\Program Files\Microsoft Visual Studio 10.0\Xml\SnippetsIndex.xml"); foreach (XmlNode node in xDoc.SelectNodes("//*")) { #> <#= node.Name #> <# } #>
Save DebugTest.tt. Verify that there are no errors, and that the resulting .txt file lists the node names in the XML file.