<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>@PCSWebLabs</title>
	<atom:link href="http://www.pcsweblabs.com/index.php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.pcsweblabs.com</link>
	<description>I.T. for the I.T. Community</description>
	<lastBuildDate>Wed, 07 Oct 2009 22:20:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Use LINQ to Query ASP.Net Control Data</title>
		<link>http://www.pcsweblabs.com/index.php/2009/07/07/use-linq-to-query-asp-net-control-data/</link>
		<comments>http://www.pcsweblabs.com/index.php/2009/07/07/use-linq-to-query-asp-net-control-data/#comments</comments>
		<pubDate>Wed, 08 Jul 2009 00:15:42 +0000</pubDate>
		<dc:creator>ramon_tristani</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[WebForms]]></category>

		<guid isPermaLink="false">http://www.pcsweblabs.com/?p=211</guid>
		<description><![CDATA[Overview [inline][/inline] The purpose of this article is to demonstrate the use of LINQ for the purpose of searching and manipulating elements from repeating controls such as an ASP.Net CheckboxList. This exercise will consist of a simple WebForm that allows the user to select a series of checkbox list items by searching within the list [...]]]></description>
			<content:encoded><![CDATA[<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Overview</h2>
[inline][/inline]
<p>
The purpose of this article is to demonstrate the use of <a href="http://msdn.microsoft.com/en-us/netframework/aa904594.aspx" target="_blank">LINQ</a> for the purpose of searching and manipulating elements from repeating controls such as an <a href="http://www.asp.net" target="_blank">ASP.Net</a> CheckboxList. This exercise will consist of a simple WebForm that allows the user to select a series of checkbox list items by searching within the list for all items containing a user defined string value. If you haven't done so already, please load <a href="http://www.microsoft.com/visualstudio/en-us/products/teamsystem/default.mspx?pt_id=-1&WT.mc_id=7CA85EDC-99B9-473E-94F1-8C6784D15490&WT.srch=1&wt.mc_id=vspdsrch" target="_blank">Visual Studio</a> and create a new web site or web application project.
</p>
<span id="more-211"></span>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The User Interface</h2>
<p>
We begin by creating a WebForm in the application. You may also opt for using the Default.aspx WebForm created by default. We will need to add the following controls:
</p>
<ul>
	<li>A TextBox</li>
	<li>A Button</li>
	<li>A CheckboxList</li>
</ul>
<p>
I have, for demonstration purposes, created the user interface with Ajax support using the built in <a href="http://www.asp.net/ajax/" target="_blank">Ajax functionality of ASP.Net</a>. The resulting markup is as follows:
</p>
<pre class="brush: xml;">
&lt;asp:updatepanel id=&quot;mainUpdate&quot; runat=&quot;server&quot;&gt;
	&lt;contenttemplate&gt;
		&lt;label&gt;
			Select items containing:
		&lt;/label&gt;
		&lt;asp:textbox id=&quot;containsText&quot; runat=&quot;server&quot; /&gt;
		&lt;asp:button id=&quot;selectFromList&quot; text=&quot;Select&quot; onclick=&quot;selectFromList_Click&quot; runat=&quot;server&quot; /&gt;
		&lt;asp:checkboxlist id=&quot;testList&quot; runat=&quot;server&quot;&gt;
			&lt;asp:listitem 
				text=&quot;Misfortune shows those who are not really friends&quot; 
				value=&quot;0&quot; /&gt;
			&lt;asp:listitem 
				text=&quot;It is wise to apply the oil of refined politeness to the mechanisms of friendship&quot; 
				value=&quot;1&quot; /&gt;
			&lt;asp:listitem 
				text=&quot;All people want is someone to listen&quot; 
				value=&quot;2&quot; /&gt;
			&lt;asp:listitem 
				text=&quot;It isn't kind to cultivate a friendship just so one will have an audience&quot; 
				value=&quot;3&quot; /&gt;
			&lt;asp:listitem 
				text=&quot;The ornament of a house is the friends who frequent it&quot; 
				value=&quot;4&quot; /&gt;
		&lt;/asp:checkboxlist&gt;
	&lt;/contenttemplate&gt;
	&lt;triggers&gt;
		&lt;asp:asyncpostbacktrigger controlid=&quot;selectFromList&quot; eventname=&quot;Click&quot; /&gt;
	&lt;/triggers&gt;
&lt;/asp:updatepanel&gt;
</pre>
<p>
Now that we have the basics, we can move on to the fun part of this exercise; the LINQ implementation that will add search based selection of the checkbox ListItem elements we've added to the list.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Implementation</h2>
<p>
We begin by creating an event handler method for the "selectFromList" button in the code behind class. This method should perform the following steps:
</p>
<ul>
	<li>Clear previously checked items</li>
	<li>Retrieve all items that contain text as entered by the user</li>
	<li>Loop through all found items and change their state to "Selected"</li>
	<li>Clear search criteria</li>
</ul>
<p>
Having established the necessary steps to fully implement our search and select functionality, we are now ready to write each step in code in the search button click event handler method as follows:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Handles search button click events
/// &lt;/summary&gt;
/// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;
/// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;
protected void selectFromList_Click(object sender, EventArgs e)
{
	// Clear all selections
	testList.ClearSelection();

	// Check for a valid string prior to executing 
	// any searches
	if (!string.IsNullOrEmpty(containsText.Text))
	{
		// Fetch all list items that match the search criteria
		// NOTE: Checkbox ListItem and search criteria text is
		// converted to lower case
		List&lt;ListItem&gt; results = (from ListItem item in testList.Items
				   where item.Text.ToLower().Contains(containsText.Text.ToLower())
				   select item).ToList();

		// When we've foound matches...
		if (results.Count &gt; 0)
		{
			// ...loop through the results and change the checkbox state to selected
			foreach (ListItem item in results)
				item.Selected = true;
		}

		// Finally, we clear the search field
		containsText.Text = string.Empty;
	}
}
</pre>
<p>
As described by the code within the search button's click event handler, the first step of our implementation deal with clearing all previously selected items by invoking the "ClearSelection" method exposed by the CheckboxList control. After verifying that a valid search string was entered by the user, we execute a LINQ query against the CheckboxList control items collection and return our matches as a list of ListItem objects with the following:
</p>
<pre class="brush: csharp;">
List&lt;ListItem&gt; results = (from ListItem item in testList.Items
	where item.Text.ToLower().Contains(containsText.Text.ToLower())
	select item).ToList();
</pre>
<p>
It is important to note that the object qualifier withing the query, "item", is indeed given a type reference of ListItem. Without this, the query simply would not work, and further, our code would not compile. All the query is responsible for at this point is to fetch all items that contain the search string specified by the user in the "containsText" TextBox control. If we have found matches, we can then process each match by changing its checked state to checked and clearing the search field with the following:
</p>
<pre class="brush: csharp;">
// When we've foound matches...
if (results.Count &gt; 0)
{
	// ...loop through the results and change the checkbox state to selected
	foreach (ListItem item in results)
		item.Selected = true;
}

// Finally, we clear the search field
containsText.Text = string.Empty;
</pre>
<p>
Our implementation is now complete
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Conclusion</h2>
<p>
In this article we have demonstrated the versatility of LINQ and used it to query control data. As shown, LINQ is a powerful tool in your arsenal that can help you write shorter, more efficient code without having to depend on complex looping and searching of item collection data.
</p>
<p>
Get the <a href='http://localhost:9000/WPBlog/wp-content/uploads/2009/05/querycontroldatalinq.zip'>source code</a> for this article.
</p>

        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <div style="width: auto; border: 1px solid silver; margin-top: 10px;"><div style="width: auto; padding: 2px; border-bottom: 1px solid silver; background-color: #F7F7F7; font-weight: bold;">Donations</div><div style="padding: 4px;"><input type="hidden" name="business" value="raytristani@gmail.com" /><input type="hidden" name="item_name" value="Donation" /><input type="hidden" name="currency_code" value="USD" /><label style="display: block; margin: 2px;">Show your support to the authors of this site. Your donation is greatly appreciated.</label><input type="image" src="http://www.pcsweblabs.com/wp-content/plugins/wp-simple-paypal-donation/btn_donate_LG.gif" name="submit" alt="Show your support to the authors of this site. Your donation is greatly appreciated." /></div></div></form>]]></content:encoded>
			<wfw:commentRss>http://www.pcsweblabs.com/index.php/2009/07/07/use-linq-to-query-asp-net-control-data/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSON Parameter String Builder</title>
		<link>http://www.pcsweblabs.com/index.php/2009/07/07/json-parameter-string-builder/</link>
		<comments>http://www.pcsweblabs.com/index.php/2009/07/07/json-parameter-string-builder/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 23:14:21 +0000</pubDate>
		<dc:creator>ramon_tristani</dc:creator>
				<category><![CDATA[Ajax]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Code Generation]]></category>
		<category><![CDATA[jQuery Ajax]]></category>

		<guid isPermaLink="false">http://www.pcsweblabs.com/?p=159</guid>
		<description><![CDATA[Overview [inline][/inline] In continuing my love affair with code generation or using code to create code, we will be creating a small jQuery based utility for creating JSON parameter strings that can be used as parameter strings to page/web methods when making Ajax calls with jQuery. While creating these strings is mostly a trivial task, [...]]]></description>
			<content:encoded><![CDATA[<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Overview</h2>
[inline][/inline]
<p>
In continuing my love affair with code generation or using code to create code, we will be creating a small jQuery based utility for creating JSON parameter strings that can be used as parameter strings to page/web methods when making Ajax calls with jQuery. While creating these strings is mostly a trivial task, the formatting that is required between parameter names and values could be error prone when build manually due to the mixing of double quotes, single quotes and the concantenation of parameter names and values. The utility we will be creating will accept two comma delimited strings, one containing parameter names and the other their matching values, combine them and output these together in JSON data parameter format. 
</p>
<span id="more-159"></span>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The User Interface</h2>
<p>
The UI for this utility is rather simple. I have added some styling to make things look "nice-a-little", but you may chose to style things to fit your needs. The UI consists of 
</p>
<ul>
	<li>
		a fieldset
	</li>
	<li>
		a table
	</li>
	<li>
		two label elements
	</li>
	<li>
		two text boxes
	</li>
	<li>
		a button
	</li>
	<li>
		a div element where the output will be shown
	</li>
<ul>
<p>
I have used the following markup to create the UI for the utility:
</p>
<pre class="brush: xml;">
&lt;fieldset style=&quot;margin: 10px; padding: 10px;&quot;&gt;
	&lt;legend&gt;
		&lt;div style=&quot;padding: 2px; border: 1px solid silver; background-color: #F1F1F1; font-weight: bold;&quot;&gt;
			JSON Parameter Format Builder
		&lt;/div&gt;
	&lt;/legend&gt;
	&lt;div style=&quot;margin-top: 6px;&quot;&gt;
		&lt;table cellpadding=&quot;2&quot; cellspacing=&quot;0&quot; border=&quot;0&quot; style=&quot;border: none;&quot;&gt;
			&lt;tr&gt;
				&lt;td&gt;
					&lt;label for=&quot;parameterNamesField&quot; style=&quot;display: block;&quot;&gt;
						Parameter Names (P1,P2,P3):
					&lt;/label&gt;
				&lt;/td&gt;
				&lt;td&gt;
					&lt;input type=&quot;text&quot; id=&quot;parameterNamesField&quot; /&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td&gt;
					&lt;label for=&quot;parameterValuesField&quot; style=&quot;display: block;&quot;&gt;
						Parameter Values (V1,V2,V3):
					&lt;/label&gt;
				&lt;/td&gt;
				&lt;td&gt;
					&lt;input type=&quot;text&quot; id=&quot;parameterValuesField&quot; style=&quot;display: block;&quot; /&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td colspan=&quot;2&quot;&gt;
					&lt;input type=&quot;button&quot; id=&quot;getParameterFormat&quot; value=&quot;Get Format&quot; /&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
				&lt;td colspan=&quot;2&quot;&gt;
					&lt;div id=&quot;parameterFormatValue&quot; style=&quot;width: 500px; height: 40px; margin: 2px; padding: 5px; border: 1px solid silver; background-color: #F1F1F1; overflow: auto;&quot; /&gt;
				&lt;/td&gt;
			&lt;/tr&gt;
		&lt;/table&gt;
	&lt;/div&gt;
&lt;/fieldset&gt;
</pre>
<p>
Once the UI has been created, we can move to the implementation details
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The Implementation</h2>
<p>
The implementation of our utility is very simple because it is 100% coded with JavaScript using <a href="http://www.jquery.com" target="_blank">jQuery</a>. In order for the utility to work correctly, it will need to do the following:
</p>
<ul>
	<li>
		Determine whether both, the parameter names string and parameter values string contain the same number of elements when split by their delimiter; in this case a comma character.
	</li>
	<li>
		Fetch the value of the parameter names field.	
	</li>
	<li>
		Fetch the value of the parameter values field.
	</li>
	<li>
		If both strings <strong>do not</strong> contain the same number of elements when split into arrays, the user should be alerted of the input error
	</li>
	<li>
		If both strings contain the same number of elements when split into arrays, then begin formatting the return string value by attaching required characters by the JSON parameter string syntax and attach parameter to value by way of a looping control structure.
	</li>
	<li>
		Return the string
	</li>
</ul>
<p>
The following JavaScript code implements our requirements:
</p>
<pre class="brush: jscript;">
$(document).ready(function() {
	// Returns a parameter string in json format
	function retrieveParamFormat(paramNames, paramValues) {
		var format = &quot;&quot;;
		var lengthsMatch = paramNames.split(&quot;,&quot;).length == paramValues.split(&quot;,&quot;).length;

		if (lengthsMatch) {
			var names = paramNames.split(&quot;,&quot;);
			var values = paramValues.split(&quot;,&quot;);

			// Prefix parameter string
			format = &quot;{&quot;;

			// Build parameter string
			for (var i = 0; i &lt; names.length; i++) {
				format += &quot;'&quot; + names[i] + &quot;':'&quot; + values[i] + &quot;'&quot;;

				if (i &lt; (names.length - 1)) {
					format += &quot;,&quot;;
				}
			}
			
			// Close parameter format
			format = format + &quot;}&quot;
		}else{
			format = 'Parameter vs. Value mismatch';
		}

		return format;
	}

	// Retrieves a json formatted parameter string
	$('#getParameterFormat').click(function() {
		var paramNames = $('#parameterNamesField').val();
		var paramValues = $('#parameterValuesField').val();

		if ((paramNames == '') || (paramValues == ''))
			alert('Parameter Names and Parameter Values are required');
		else
			$('#parameterFormatValue').html(retrieveParamFormat(paramNames, paramValues));
	});
});
</pre>
<p>
<strong>Demo</strong>
</p>
[inline]
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
	// Returns a parameter string in json format
	function retrieveParamFormat(paramNames, paramValues) {
		var format = "";
		var lengthsMatch = paramNames.split(",").length == paramValues.split(",").length;

		if (lengthsMatch) {
			var names = paramNames.split(",");
			var values = paramValues.split(",");

			// Prefix parameter string
			format = "{";

			// Build parameter string
			for (var i = 0; i < names.length; i++) {
				format += "'" + names[i] + "':'" + values[i] + "'";

				if (i < (names.length - 1)) {
					format += ",";
				}
			}
			
			// Close parameter format
			format = format + "}"
		}else{
			format = 'Parameter vs. Value mismatch';
		}

		return format;
	}

	// Retrieves a json formatted parameter string
	$('#getParameterFormat').click(function() {
		var paramNames = $('#parameterNamesField').val();
		var paramValues = $('#parameterValuesField').val();

		if ((paramNames == '') || (paramValues == ''))
			alert('Parameter Names and Parameter Values are required');
		else
			$('#parameterFormatValue').html(retrieveParamFormat(paramNames, paramValues));
	});
});
</script>
[/inline]
<fieldset style="margin: 10px; padding: 10px;">
	<legend>
		<div style="padding: 2px; border: 1px solid silver; background-color: #F1F1F1; font-weight: bold;">
			JSON Parameter Format Builder
		</div>
	</legend>
	<div style="margin-top: 6px;">
		<table cellpadding="2" cellspacing="0" border="0" style="border: none;">
			<tr>
				<td>
					<label for="parameterNamesField" style="display: block;">
						Parameter Names (P1,P2,P3):
					</label>
				</td>
				<td>
					<input type="text" id="parameterNamesField" />
				</td>
			</tr>
			<tr>
				<td>
					<label for="parameterValuesField" style="display: block;">
						Parameter Values (V1,V2,V3):
					</label>
				</td>
				<td>
					<input type="text" id="parameterValuesField" style="display: block;" />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<input type="button" id="getParameterFormat" value="Get Format" />
				</td>
			</tr>
			<tr>
				<td colspan="2">
					<div id="parameterFormatValue" style="width: 500px; height: 40px; margin: 2px; padding: 5px; border: 1px solid silver; background-color: #F1F1F1; overflow: auto;" />
				</td>
			</tr>
		</table>
	</div>
</fieldset>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Use Case</h2>
<p>
Now that we have a function that will create JSON parameter strings for us all we have to do is utilize its output with an actual Ajax call to a web service. The following is a sample of how this can be achieved:
</p>
<pre class="brush: jscript;">
var serviceUrl = 'http://www.someservicehost.com/someservice.asmx/somemethod';

// Get parameter format
var format = retrieveParamFormat('name,age,address', 'Ramon E. Tristani,39,some address in the beautiful state of WA');

// Execute Ajax call
$.ajax({
	type: 'POST',
	url: serviceUrl,
	data: format,
	contentType: 'application/json; charset=utf-8',
	dataType: 'json',
	success: function(result) {
		$('#&lt;%= pageMethodNameGreetingField.ClientID %&gt;').val(result.d);
	},
	error: function() {
		alert('An error occurred while accessing the the following web service:\n'
			+ serviceUrl);
	}
});
</pre>
<p>
In the aove sample I have provided hard-coded strings. In a real life situation however, these values should come from data input elements within the HTML document
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Conclusion</h2>
<p>
In this article we have created a simple utility to automate the creation of data parameter strings used in Ajax calls. Having quick utility functions like these that handle repetitive tasks is important as it will reduce the amount of debugging and application showstopping points, while increasing application maintainability.
</p>
<p>
Get the <a href='http://www.pcsweblabs.com/wp-content/uploads/2009/07/JSONParameterStringBuilder.zip'>source code</a> for this article.
</p>

        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <div style="width: auto; border: 1px solid silver; margin-top: 10px;"><div style="width: auto; padding: 2px; border-bottom: 1px solid silver; background-color: #F7F7F7; font-weight: bold;">Donations</div><div style="padding: 4px;"><input type="hidden" name="business" value="raytristani@gmail.com" /><input type="hidden" name="item_name" value="Donation" /><input type="hidden" name="currency_code" value="USD" /><label style="display: block; margin: 2px;">Show your support to the authors of this site. Your donation is greatly appreciated.</label><input type="image" src="http://www.pcsweblabs.com/wp-content/plugins/wp-simple-paypal-donation/btn_donate_LG.gif" name="submit" alt="Show your support to the authors of this site. Your donation is greatly appreciated." /></div></div></form>]]></content:encoded>
			<wfw:commentRss>http://www.pcsweblabs.com/index.php/2009/07/07/json-parameter-string-builder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Service Calls With jQuery Ajax</title>
		<link>http://www.pcsweblabs.com/index.php/2009/07/05/web-service-calls-with-jquery-ajax/</link>
		<comments>http://www.pcsweblabs.com/index.php/2009/07/05/web-service-calls-with-jquery-ajax/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 03:28:35 +0000</pubDate>
		<dc:creator>ramon_tristani</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[Web Services]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[jQuery Ajax]]></category>
		<category><![CDATA[Web Service]]></category>
		<category><![CDATA[WebForms]]></category>
		<category><![CDATA[WebMethod]]></category>

		<guid isPermaLink="false">http://www.pcsweblabs.com/?p=128</guid>
		<description><![CDATA[Overview [inline][/inline] In this article we will explore web service calls with jQuery Ajax from ASP.Net webforms. We will be doing this without the use of an ASP.Net UpdatePanel by performing all Ajax calls directly with jQuery. In my opinion, Ajax calls are far more efficient when making the Ajax call directly because we bypass [...]]]></description>
			<content:encoded><![CDATA[<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Overview</h2>
[inline][/inline]
<p>
In this article we will explore web service calls with jQuery Ajax from ASP.Net webforms. We will be doing this without the use of an ASP.Net UpdatePanel by performing all Ajax calls directly with jQuery. In my opinion, Ajax calls are far more efficient when making the Ajax call directly because we bypass the overhead of update panels, refreshing the HTML we want to refresh directly, rather than refreshing all the content of the UpdatePanel ContentTemplate HTML on every partial postback. While there is JavaScript code to be written to accomplish this, the impact is minimal and with some usage and experience, the task becomes trivial over time. 
</p>
<span id="more-128"></span>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The User Interface</h2>
<p>
We begin by creating an ASP.Net web application in Visual Studio .Net. By default, the project template will create the Default.aspx WebForm which will be a suitable WebForm to use for the purposes of this tutorial. Once the project is created, make sure a reference to the jQuery Library has been made by adding the appropriate script tags to the HEAD element of the Default.aspx WebForm. Let's begin by creating the following user interface:
</p>
<pre class="brush: xml;">
&lt;%@ Page Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;WebServiceCallsArticleUI.aspx.cs&quot; Inherits=&quot;jQueryWebServicesAndPageMethods.WebServiceCallsArticleUI&quot; %&gt;
&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head id=&quot;Head1&quot; runat=&quot;server&quot;&gt;
	&lt;title&gt;Web Service Calls With jQuery Ajax&lt;/title&gt;
	&lt;style type=&quot;text/css&quot;&gt;
		body { font-family: Comic Sans MS; font-size: 10pt; }
		h1 { color: #ffffff; background-color: #456984; padding: 3px; font-size: 18px; margin-top: 0px; }
		label { margin-top: 5px; display: block; }
		input[type=text] { width: 200px; }
		select { width: 200px; }
		fieldset { margin: 10px; padding: 5px; }
		legend { font-weight: bold; }
		#wrapper { border: 1px solid #c1c1c1; padding-bottom: 10px; }
	&lt;/style&gt;
	&lt;script src=&quot;Assets/Scripts/jquery-1.3.2.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot;&gt;
		$(document).ready(function() { 
			// Add supporting code here
		});
	&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;form id=&quot;mainForm&quot; runat=&quot;server&quot;&gt;
	&lt;div id=&quot;wrapper&quot;&gt;
		&lt;h1&gt;
			Using jQuery Ajax
		&lt;/h1&gt;
		&lt;fieldset&gt;
			&lt;legend&gt;Web Service Calls with Ajax&lt;/legend&gt;
			&lt;div&gt;
				&lt;label for='&lt;%= serviceGreetingTextField.ClientID  %&gt;'&gt;
					From Web Service:
				&lt;/label&gt;
				&lt;asp:textbox id=&quot;serviceGreetingTextField&quot; runat=&quot;server&quot; /&gt;
				&lt;input type=&quot;button&quot; id=&quot;serviceMethodGetGreeting&quot; value=&quot;Greet&quot; /&gt;
				&lt;input type=&quot;button&quot; id=&quot;serviceValueReset&quot; value=&quot;Reset&quot; /&gt;
				&lt;img id=&quot;serviceGreetingIndicator&quot; src=&quot;Assets/Images/Snake456984.gif&quot; alt=&quot;Working...&quot; class=&quot;progressIndication&quot; /&gt;
			&lt;/div&gt;
		&lt;/fieldset&gt;
		&lt;fieldset&gt;
			&lt;legend&gt;Web Service Calls with Ajax (with parameters)&lt;/legend&gt;
			&lt;div&gt;
				&lt;label for='&lt;%= serviceNameField.ClientID  %&gt;'&gt;
					First Name:
				&lt;/label&gt;
				&lt;asp:textbox id=&quot;serviceNameField&quot; runat=&quot;server&quot; /&gt;
				&lt;input type=&quot;button&quot; id=&quot;getServiceNameGreeting&quot; value=&quot;Greet&quot; /&gt;
				&lt;input type=&quot;button&quot; id=&quot;resetServiceNameGreeting&quot; value=&quot;Reset&quot; /&gt;
				&lt;label for='&lt;%= serviceNameGreetingField.ClientID  %&gt;'&gt;
					Greeting:
				&lt;/label&gt;
				&lt;asp:textbox id=&quot;serviceNameGreetingField&quot; runat=&quot;server&quot; /&gt;
				&lt;img id=&quot;serviceNameGreetingIndicator&quot; src=&quot;Assets/Images/Snake456984.gif&quot; alt=&quot;Working...&quot; class=&quot;progressIndication&quot; /&gt;
			&lt;/div&gt;
		&lt;/fieldset&gt;
		&lt;fieldset&gt;
			&lt;legend&gt;Adding Items to a List From a WebService&lt;/legend&gt;
			&lt;div&gt;
				&lt;label for='&lt;%= testList.ClientID  %&gt;'&gt;
					List Items:
				&lt;/label&gt;
				&lt;asp:dropdownlist id=&quot;testList&quot; runat=&quot;server&quot;&gt;
					&lt;asp:listitem value=&quot;-1&quot; text=&quot;-- Select --&quot; /&gt;
				&lt;/asp:dropdownlist&gt;
				&lt;input type=&quot;button&quot; id=&quot;testListAddItems&quot; value=&quot;Get Items&quot; /&gt;
				&lt;input type=&quot;button&quot; id=&quot;testListReset&quot; value=&quot;Reset&quot; /&gt;
				&lt;img id=&quot;testListIndicator&quot; src=&quot;Assets/Images/Snake456984.gif&quot; alt=&quot;Working...&quot; class=&quot;progressIndication&quot; /&gt;
			&lt;/div&gt;
		&lt;/fieldset&gt;
	&lt;/div&gt;
	&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>
Once the UI is created, we should end up with something similar to the following screen capture:
</p>
<div id="attachment_132" class="wp-caption alignnone" style="width: 433px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/06/WebServiceCallsWithjQueryAjaxUI.PNG" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/06/WebServiceCallsWithjQueryAjaxUI.PNG" alt="User Interface" title="User Interface" width="423" height="371" class="size-full wp-image-132" /></a><p class="wp-caption-text">User Interface</p></div>
<p>
While we are at it, do save the progress indicator image shown in the screen capture by right clicking the image below and saving it to the images folder in your web application. We will be using this image as a progress indicator for each of our fieldset elements as we execute each Ajax call.
</p>
<div id="attachment_131" class="wp-caption alignnone" style="width: 140px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/06/Snake456984.gif" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/06/Snake456984.gif" alt="Progress Indicator" title="Progress Indicator" width="16" height="16" class="size-full wp-image-131" /></a><p class="wp-caption-text">Progress Indicator</p></div>
<p>
Now that we have a UI to work with we can assume that we will be making 3 different Ajax calls. These are:
</p>
<ul>
	<li>
		A call to retrieve a greeting from a web service similar to "Hello World"
	</li>
	<li>
		A call to retrieve a greeting from a web service by passing a first name parameter
	</li>
	<li>
		A call to retrieve a list of greetings from a web service that will populate a dropdown list
	</li>
</ul>
<p>
The web methods we will be calling have been made extremely simple just for the purpose of demonstrating the concepts involved in making these Ajax calls. However, using this methodology, you are certainly able to create more complex methods that return more complex data. That said, the first two calls will be returning simple strings, while the last call we will use for populating the dropdown list, will return an object of type <pre class="brush: csharp;">List&lt;string&gt;</pre>
</p>
<p>
Let's get started!
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Web Service Implementation</h2>
<p>
The first thing that we must do is create a web service application in the same solution where we created our web application. I chose to name this project
</p>
<ul>
	<li>
		SampleServices
	</li>
</ul>
<p>
Once the web service application project has been created, the application should be converted to an IIS web application if IIS is available in the development system. To do so, follow these steps:
</p>
<ul>
	<li>
		Right click the web service application project and select "Properties" from the context menu
	</li>
	<li>
		In the properties window, select the "Web" tab on the left side of the properties window.
	</li>
	<li>
		Click the "Use Local IIS server" option towards the bottom of the options window
	</li>
	<li>
		While I chose to use "http://localhost/SampleServices" for my virtual directory, you may chose an URL of your choice.
	</li>
	<li>
		Save the properties and close the properties window
	</li>
</ul>
<p>
Now that we have a local IIS site, we are able to provide this address to the URL parameter of the ajax call within the jQuery code. By default, when the web service application was created, Visual Studio created a default web service called
</p>
<ul>
	<li>
		Service1.asmx
	</li>
</ul>
<p>
Go ahead an delete that service and add a new one called
</p>
<ul>
	<li>
		SimpleService.asmx
	</li>
</ul>
<p>
Once the new service class has been created, right click the file and select "View Code" from the context menu and add the following code:
</p>
<pre class="brush: csharp;">
namespace SampleServices
{
	/// &lt;summary&gt;
	/// Summary description for SimpleService
	/// &lt;/summary&gt;
	[WebService(Namespace = &quot;http://tempuri.org/&quot;)]
	[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
	[System.ComponentModel.ToolboxItem(false)]
	[System.Web.Script.Services.ScriptService]
	public class SimpleService : System.Web.Services.WebService
	{
		[WebMethod]
		public string HelloWorld()
		{
			System.Threading.Thread.Sleep(500);
			return &quot;Hello World From Web Service&quot;;
		}

		[WebMethod]
		public string HelloWho(string name)
		{
			System.Threading.Thread.Sleep(500);
			return string.Format(&quot;Hello {0}!&quot;, name);
		}

		[WebMethod]
		public List&lt;string&gt; GreetingList()
		{
			System.Threading.Thread.Sleep(500);
			List&lt;string&gt; retVal = new List&lt;string&gt;();
			retVal.Add(&quot;Jim&quot;);
			retVal.Add(&quot;John&quot;);
			retVal.Add(&quot;Joe&quot;);

			return retVal;
		}
	}
}
</pre>
<p>
We now have three web methods with the following names and purpose:
</p>
<ul>
	<li>
		<strong>HelloWorld:</strong> Will return a hard coded greeting string
	</li>
	<li>
		<strong>HelloWho:</strong> Will return a formatted string with a parameter passed into it by the caller
	</li>
	<li>
		<strong>GreetingList:</strong> Will return a string array containing names that will be further formatted to show greetings in list fashion
	</li>
</ul>
<p>
Once the service is complete, build the project and if all goes well, close the web service class editor as we have now fully implemented the web service itself and will be focusing on the JavaScript we need in order to bring the UI and the web service work together.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">jQuery Implementation</h2>
<p>
If not already open for editing, open the Default.aspx webform in source view and locate the following empty script tag we created along with the UI:
</p>
<pre class="brush: xml;">
&lt;script type=&quot;text/javascript&quot;&gt;
	$(document).ready(function() { 
		// Add supporting code here
	});
&lt;/script&gt;
</pre>
<p>
We will be doing the bulk of our work inside of the "$(document).ready" event. One of the nicest things about jQuery is the way that it wires up all page control events when the document first loads. This way, we are not constrained into coding events into our html elements and thus truly separating UI implementation from UI behavior. We will then take advantage of this functionality and begin wiring up a set of element events that when fired, will in turn execute Ajax calls against the web service we have already created. Let's begin by adding the following code inside of the "$(document).ready" event carefully noting the variable "indicatorID which resides outside of "$(document).ready":
</p>
<pre class="brush: jscript;">
// Progress indicator placeholder var
var indicatorID = '';

$(document).ready(function() { 
	// Hide all progress indicators
	$('.progressIndication').hide();
			
	// Clears reseting of web service value
	$('#serviceValueReset').click(function() {
		if ($('#serviceGreetingTextField').val() == '')
			alert('The field is empty');
		else
			$('#serviceGreetingTextField').val('');
	});

	// Retrieves a greeting from a web service
	$('#serviceMethodGetGreeting').click(function() {
		// Set indicator id
		indicatorID = '#serviceGreetingIndicator';

		// Clear field value
		$('#&lt;%= serviceGreetingTextField.ClientID %&gt;').val('');

		// Ajax URL
		var serviceUrl = 'http://localhost/SampleServices/SimpleService.asmx/HelloWorld';

		// Execute Ajax call
		$.ajax({
			type: 'POST',
			url: serviceUrl,
			data: '{}',
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			success: function(result) {
				$('#&lt;%= serviceGreetingTextField.ClientID %&gt;').val(result.d);
			},
			error: function() {
				alert('An error occurred while accessing the the following web service:\n'
				+ serviceUrl);
			}
		});
	});
});
</pre>
<p>
<strong>Outside of the "$(document).ready" event</strong> add the following code:
</p>
<pre class="brush: jscript;">
// Progress indicator
$(document).ajaxStart(function() {
	if (!(indicatorID == '')) {
		$(indicatorID).show();
	}
}).ajaxStop(function() {
	if (!(indicatorID == '')) {
		$(indicatorID).hide();
		indicatorID = '';
	}
});
</pre>
<p>
We have accomplished three things here:
</p>
<ul>
	<li>
		<strong>$('#serviceValueReset').click:</strong> We have created an event for the reset button on the first fieldset element that will clear any data already present in any of the fields located within the first fieldset.
	</li>
	<li>
		<strong>$('#serviceMethodGetGreeting').click:</strong> We have created an event that will execute the Ajax call against the web service method that will in turn return a value that will populate the "serviceGreetingTextField" textbox.
	</li>
	<li>
		<strong>$(document).ajaxStart().ajaxStop():</strong> We have created the necessary plumbing that will allow our webform to display a progress indicator next to the elements that will be affected by the Ajax call
	</li>
</ul>
<p>
<strong>...and this is how this works:</strong>
</p>
<ol>
	<li>
		<strong>$('#serviceValueReset').click</strong> references the textbox element and detects whether it is necessary to clear it or not, alerting the user of this fact. If the field has content, it simply clears it by setting its value to an empty string.
	</li>
	<li>
		<strong>$('#serviceMethodGetGreeting').click</strong> responds to click events fired by the "serviceMethodGetGreeting" button. Next it sets the "indicatorID" variable to the indicator image ID associated with the element being updated by the ajax call to the web service. After this is done, the textbox is cleared of any content by setting its value to an empry string. Now that the form is ready to be updated, the web service URL along with the method we intend to call is stored in string format into a variable. It is important to make sure this URL is formatted correctly or else the call will simply fail. 
	</li>
	<li>
		<strong>$.ajax</strong> is given all the options it needs in order to execute the call to the web service by setting the following options
		<ul>
			<li>
				<strong>type:</strong> Since we are using JSON, this value is set to use the "POST" form method.
			</li>
			<li>
				<strong>url:</strong> This is the web service [URL + "/" + METHOD_NAME]
			</li>
			<li>
				<strong>data:</strong> Since we are not passing parameters to the web service, we pass the JSON equivalent of NULL "{}"
			</li>
			<li>
				<strong>contentType:</strong> The application content type which happens to be "application/json; charset=utf-8"
			</li>
			<li>
				<strong>dataType:</strong> THis value is set to "json" since this is the format in which we are making the call to the web service
			</li>
			<li>
				<strong>success:</strong> This is a callback function that will be executed if the Ajax call was successful and therefore the function we use in order to update the form elements
			</li>
			<li>
				<strong>error:</strong> This is the callback function that will be executed in the unfortunate event an error occurs. It simply displays an alert to the user stating that an error has occurred.
			</li>
		</ul>	
	</li>
	<li>
		<strong>$(document).ajaxStart().ajaxStop():</strong> This is where our progress indicators are shown or hidden. They are displayed when the Ajax call is initiated and hidden upon termination. This is why the "indicatorID" variable is set when the "serviceMethodGetGreeting" is fired. In this way, the "$(document).ajaxStart().ajaxStop()" events are aware of which indicator to show or hide and when.
	</li>
</ol>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">jQuery Implementation... The Rest</h2>
<p>
Having now implemented the support code for the first fieldset element on the webform, we can now add the rest of the code and go through the highlights of what it is doing differently from the code we've just implemented. Add the following code below the "$('#serviceMethodGetGreeting').click" event block:
</p>
<pre class="brush: jscript;">
// Retrieves a greeting from a web service by passing parameters
$('#getServiceNameGreeting').click(function() {
	var firstName = $('#&lt;%= serviceNameField.ClientID %&gt;').val();
	if (firstName != '') {
		// Set indicator id
		indicatorID = '#serviceNameGreetingIndicator';

		// Clear field value
		$('#&lt;%= serviceNameGreetingField.ClientID %&gt;').val('');

		// Ajax URL. 
		var serviceUrl = 'http://localhost/SampleServices/SimpleService.asmx/HelloWho';

		// Get parameter format
		var format = &quot;{'name':'&quot; + firstName + &quot;'}&quot;;

		// Execute Ajax call
		$.ajax({
			type: 'POST',
			url: serviceUrl,
			data: format,
			contentType: 'application/json; charset=utf-8',
			dataType: 'json',
			success: function(result) {
				$('#&lt;%= serviceNameGreetingField.ClientID %&gt;').val(result.d);
			},
			error: function() {
				alert('An error occurred while accessing the the following web service:\n'
					+ serviceUrl);
			}
		});
	} else {
		alert('First Name is required');
	}
});

// Clears reseting of web service value
$('#resetServiceNameGreeting').click(function() {
	if ($('#serviceNameField').val() == '' || $('#serviceNameField').val() == '')
		alert('The field is empty');
	else {
		$('#serviceNameField').val('');
		$('#serviceNameGreetingField').val('');
	}
});

$('#testListAddItems').click(function() {
	// Set indicator id
	indicatorID = '#testListIndicator';

	// Ajax URL. 
	var serviceUrl = 'http://localhost/SampleServices/SimpleService.asmx/GreetingList';

	// Execute Ajax call
	$.ajax({
		type: 'POST',
		url: serviceUrl,
		data: '{}',
		contentType: 'application/json; charset=utf-8',
		dataType: 'json',
		success: function(result) {
			$.each(result.d, function(i, text) {
				$('#&lt;%= testList.ClientID %&gt;').append($('&lt;option&gt;&lt;/option&gt;').val(i).html('Hello ' + text));
			});
		},
		error: function(xmlHttpRequest, status, error) {
			var errorStatus = xmlHttpRequest.status;
			var errorText = xmlHttpRequest.responseText;
			var statusText = xmlHttpRequest.statusText;

			alert('Error Status: ' + errorStatus + '\n'
				+ 'Error Message: ' + errorText + '\n'
				+ 'Status Info: ' + statusText + '\n');
		}
	});
});

// Resets the test list
$('#testListReset').click(function() {
	$('#&lt;%= testList.ClientID %&gt; &gt;option').remove();
	$('#&lt;%= testList.ClientID %&gt;').append($('&lt;option&gt;&lt;/option&gt;').val('-1').html('-- Select --'));
});
</pre>
<p>
<strong>And now the highlights...</strong>
</p>
<p>
As seen in the first example, an event is attached to each of the buttons that will trigger an Ajax call. In this case, the "$('#getServiceNameGreeting').click" event is attached to the "getServiceNameGreeting" button. In addition to the usual boiler-plate code in which we set up the service URL and Ajax parameters, we created a parameter format variable that contains the "parameter name/value" pair that must be passed to the web service for the intended web service call. This parameter format is very important because a simple typo will force the Ajax event to fire the "error" callback instead of the "success" callback and therefore failing the exacution of the web service call. The syntax for this format is not very complicated but rather easy to mess up, especially when more than one parameter must be used. In short, if the WebMethod signature contains parameters "p1, p2, p3" then our parameter string should look like the following:
</p>
<ul>
	<li>
		{'p1':'v1','p2':'v2','p3':'v3'}
	</li>
</ul>
<p>
As seen above, good attention to detail should be exercised when building these strings because even though it is a very simple string format, it is even simpler to get mess up.  Once we get passed the parameter format, the Ajax call is exacuted against the web service in much the same fashion as before
</p>
<p>
The last part of the implementation deals with binding a dropdown list from yet another web service method. In this case, the web service call is nearly identical to the first service call in our implementation. The one difference is that while the first two code implementations dealt with string results being returned from the web services, the last web method we will call will return an object of type List<string> <strong>as an array of strings</strong>. We must remember that this Ajax call is of type JSON and as such, these list items will be return as arrays; remembering that JavaScript is type agnostic. 
</p>
<p>
Understanding this, all that remains is the addition tof the <option/> elements to our dropdown list. This too, we shall accomplish with jQuery by iterating through the returned items by the web service by way of the "success" callback function.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Conclusion</h2>
<p>
In this we have covered the very basic concepts of executing Ajax calls against web services, returning values, arrays, passing parameters and manipulating UI elements to respond to Ajax activity. Additionally we have explored the flexibility that making these calls manually will give you as you dig deeper and move away from the usual update panel here and update progress there pattern of ASP.Net Ajax controls. While these methods are useful and certainly worth learning, learning how not to depend on those controls will be a skill you will thank your self over and over again for learning when blackbox code such as that of ASP.Net Ajax fails or behaves buggy and erratic.
</p>
<p>
Get the <a href='http://www.pcsweblabs.com/wp-content/uploads/2009/07/jqueryajax1.zip'>source code</a> for this article.
</p>


        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <div style="width: auto; border: 1px solid silver; margin-top: 10px;"><div style="width: auto; padding: 2px; border-bottom: 1px solid silver; background-color: #F7F7F7; font-weight: bold;">Donations</div><div style="padding: 4px;"><input type="hidden" name="business" value="raytristani@gmail.com" /><input type="hidden" name="item_name" value="Donation" /><input type="hidden" name="currency_code" value="USD" /><label style="display: block; margin: 2px;">Show your support to the authors of this site. Your donation is greatly appreciated.</label><input type="image" src="http://www.pcsweblabs.com/wp-content/plugins/wp-simple-paypal-donation/btn_donate_LG.gif" name="submit" alt="Show your support to the authors of this site. Your donation is greatly appreciated." /></div></div></form>]]></content:encoded>
			<wfw:commentRss>http://www.pcsweblabs.com/index.php/2009/07/05/web-service-calls-with-jquery-ajax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Generation Part II &#8211; Creating a Code Generator With C#, XML and XSLT</title>
		<link>http://www.pcsweblabs.com/index.php/2009/06/06/code-generation-creating-a-code-generator-with-c-xml-and-xslt/</link>
		<comments>http://www.pcsweblabs.com/index.php/2009/06/06/code-generation-creating-a-code-generator-with-c-xml-and-xslt/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 22:16:02 +0000</pubDate>
		<dc:creator>ramon_tristani</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code Generation]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Console Application]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[XSL]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://www.pcsweblabs.com/?p=94</guid>
		<description><![CDATA[Overview [inline][/inline] This article is the second in a series of Code Generation articles that will demonstrate the basic concepts of using code in combination with freely available tools to generate code and eliminate hours of tedious and repetitive work. This article builds on the previous article in both knowledge and code and is recommended [...]]]></description>
			<content:encoded><![CDATA[<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Overview</h2>
[inline][/inline]
<p>
This article is the second in a series of <a href="http://www.pcsweblabs.com/index.php/category/code-generation/" target="_blank">Code Generation</a> articles that will demonstrate the basic concepts of using code in combination with freely available tools to generate code and eliminate hours of tedious and repetitive work. This article builds on the previous article in both knowledge and code and is recommended reading prior to moving forward. In this article we will examine key concepts in generating code from XML metadata with XML related objects from the <a href="http://msdn.microsoft.com/en-us/library/system.xml.xsl.aspx" target="_blank">System.Xml.Xsl</a> assembly of the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">Microsoft .Net Framework</a>. This article will deal with the following and build upon:
</p>
<ul>
	<li>
		Specifying new elements in the App.config file, wrapping the keys in the LibraryConstants class, and new properties to the CoreBase class that will expose values set in the App.config file
	</li>
	<li>
		Add support enumerations and classes to the CodeGenerator.Core assembly 
	</li>
	<li>
		Creating the CodeBuilder class that will derive from MetadataGenerator in order to create a single point of execution for code generation purposes
	</li>
	<li>
		Create basic templates for the generation of stored procedures based on our database schema
	</li>
	<li>
		Modifying the CodeGenerator application to make use of the finished CodeGenerator.Core assembly
	</li>
</ul>
<span id="more-94"></span>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Review</h2>
<p>
At this stage in the <a href="http://www.pcsweblabs.com/index.php/2009/05/29/code-generation-extract-database-metadata/" target="_blank">Code Generation</a> project we have a basic console application that is able to extract SQL Server database metadata from the code generation target and display this data in XML format to the output screen. The application is able to do this by way of the CodeGenerator.Core assembly. It is this assembly that we will continue to expand further and give the assembly the ability to not just retrieve required metadata, but use this metadata for code generation purposes. 
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Configuration Options</h2>
<p>
We begin this section with the App.config file in the console application. We must edit this file in order to add information about XSL template file paths as well as generator output paths. Once the App.config has been fully modified, we will add the configuration keys to the LibraryConstants class and further modify the CoreBase class to expose these configuration elements as properties to all derived classes. Before we do so, let's first modify the console application project and add stub files (empty files) for the XSL templates. We will code these templates last as doing so now will become a distraction from our main goal which is to build a code generator. Let's begin by adding a folder to the console application project and naming it "Templates". Once done, add the following stub XSL files and name them as shown here:
</p>
<ul>
	<li>
		Templates
		<ul>
			<li>
				DeleteProcedure.xsl
			</li>
			<li>
				InsertProcedure.xsl
			</li>
			<li>
				SearchProcedure.xsl
			</li>
			<li>
				SelectProcedure.xsl
			</li>
			<li>
				UpdateProcedure.xsl
			</li>
		</ul> 
	</li>
</ul>
<p>
We are now ready to modify the App.config file and add template path information. To do so, load the configuration file in Visual Studio and add the following elements to the "appSettings" section:
</p>
<pre class="brush: xml;">
&lt;!-- OUTPUT OPTIONS --&gt;
&lt;add key=&quot;OutputRoot&quot; value=&quot;C:\Code Generator Output&quot; /&gt;
		
&lt;!-- STORED PROCEDURE TEMPLATES --&gt;
&lt;add key=&quot;DeleteProcedureTemplatePath&quot; value=&quot;[PATH TO FILE]\DeleteProcedure.xsl&quot; /&gt;
&lt;add key=&quot;InsertProcedureTemplatePath&quot; value=&quot;[PATH TO FILE]\InsertProcedure.xsl&quot; /&gt;
&lt;add key=&quot;SearchProcedureTemplatePath&quot; value=&quot;[PATH TO FILE]\SearchProcedure.xsl&quot; /&gt;
&lt;add key=&quot;SelectProcedureTemplatePath&quot; value=&quot;[PATH TO FILE]\SelectProcedure.xsl&quot; /&gt;
&lt;add key=&quot;UpdateProcedureTemplatePath&quot; value=&quot;[PATH TO FILE]\UpdateProcedure.xsl&quot; /&gt;
</pre>
<p>
Next, we need to modify the path to the XSL templates in the configuration elements. We do this by deleting the data in the "value" attribute of the element and from the solutions explorer, drag and drop the XSL template file into the value attribute. The result of this operation will be the inclusion of the file path directly into the value attribute of the configuration element.
</p>
<p>
The next task at hand will be to modify the CodeGenerator.Core.LibraryConstants class. Load this class and modify the file by adding the following constants:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Code file output root directory key
/// &lt;/summary&gt;
public const string OUTPUT_ROOT = &quot;OutputRoot&quot;;
/// &lt;summary&gt;
/// Delete procedure template path
/// &lt;/summary&gt;
public const string TEMPLATE_PATH_DELETE_PROCEDURE = &quot;DeleteProcedureTemplatePath&quot;;
/// &lt;summary&gt;
/// Insert procedure template path
/// &lt;/summary&gt;
public const string TEMPLATE_PATH_INSERT_PROCEDURE = &quot;InsertProcedureTemplatePath&quot;;
/// &lt;summary&gt;
/// Search procedure template path
/// &lt;/summary&gt;
public const string TEMPLATE_PATH_SEARCH_PROCEDURE = &quot;SearchProcedureTemplatePath&quot;;
/// &lt;summary&gt;
/// Select procedure template path
/// &lt;/summary&gt;
public const string TEMPLATE_PATH_SELECT_PROCEDURE = &quot;SelectProcedureTemplatePath&quot;;
/// &lt;summary&gt;
/// Update procedure template path
/// &lt;/summary&gt;
public const string TEMPLATE_PATH_UPDATE_PROCEDURE = &quot;UpdateProcedureTemplatePath&quot;;
/// &lt;summary&gt;
/// Stored procedures folder name
/// &lt;/summary&gt;
public const string FOLDER_NAME_STORED_PROCEDURE = &quot;Stored Procedures&quot;;
</pre>
<p>
These are the constants that we will use against the properties being exposed by the CoreBase class. Load the CoreBase class and modify the class by adding the following properties:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Gets OutputFolderRoot
/// &lt;/summary&gt;
protected string OutputFolderRoot
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.OUTPUT_ROOT];
	}
}
/// &lt;summary&gt;
/// Gets DeleteProcedureTemplatePath
/// &lt;/summary&gt;
protected string DeleteProcedureTemplatePath
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.TEMPLATE_PATH_DELETE_PROCEDURE];
	}
}
/// &lt;summary&gt;
/// Gets InsertProcedureTemplatePath
/// &lt;/summary&gt;
protected string InsertProcedureTemplatePath
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.TEMPLATE_PATH_INSERT_PROCEDURE];
	}
}
/// &lt;summary&gt;
/// Gets SearchProcedureTemplatePath
/// &lt;/summary&gt;
protected string SearchProcedureTemplatePath
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.TEMPLATE_PATH_SEARCH_PROCEDURE];
	}
}
/// &lt;summary&gt;
/// Gets SelectProcedureTemplatePath
/// &lt;/summary&gt;
protected string SelectProcedureTemplatePath
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.TEMPLATE_PATH_SELECT_PROCEDURE];
	}
}
/// &lt;summary&gt;
/// Gets UpdateProcedureTemplatePath
/// &lt;/summary&gt;
protected string UpdateProcedureTemplatePath
{
	get
	{
		return ConfigurationManager.AppSettings[LibraryConstants.TEMPLATE_PATH_UPDATE_PROCEDURE];
	}
}
</pre>
<p>
As seen in the CoreBase code we added, all new element values from the configuration file have been properly exposed by way of the CoreBase class and therefore being made available to all derived classes within the CodeGenerator.Core assembly and concludes the configuration support for the purposes of this article. 
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Support Enumerations</h2>
<p>
Before we create the CodeBuilder class, we will need two enumerations
</p>
<ul>
	<li>
		FolderTypes
	</li>
	<li>
		TemplateTypes
	</li>
</ul>
<p>
These enumerations will control and identify necessary generation operations and help the assembly determine paths for generated outputs. Usage of these enumerations will become more clear as we move along. Add a new class file to the CodeGenerator.Core assembly and name it "FolderTypes". When loaded in the editor, modify the file to contain the following code:
</p>
<pre class="brush: csharp;">
#region Using namespaces...
using System;
#endregion

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// FolderTypes enumeration
	/// &lt;/summary&gt;
	public enum FolderTypes
	{
		/// &lt;summary&gt;
		/// StoredProcedureOutput folder type enumeration member
		/// &lt;/summary&gt;
		StoredProcedureOutput
	}
}
</pre>
<p>
The next enumeration to create will be the TemplateTypes enumeration. Again, add a new class file to the CodeGenerator.Core assembly, name it "TemplateTypes" and add the following code to the file:
</p>
<pre class="brush: csharp;">
#region Using namespaces...
using System;
#endregion

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// TemplateTypes enumeration
	/// &lt;/summary&gt;
	public enum TemplateTypes
	{
		/// &lt;summary&gt;
		/// StoredProcedureTemplates template type enumeration member
		/// &lt;/summary&gt;
		StoredProcedureTemplate
	}
}
</pre>
<p>
All necessary support plumbing should be in place now and therefore, we are now able to move on to the CodeBuilder class.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">On to Code Generation</h2>
<p>
Code generation is a process that involves many smaller steps and while it might seem like a complex process, in reality it is a very simple process depending on how the process is divided and data is organized. We begin organizing these code generation tasks with the creation of the CodeBuilder class in the CodeGenerator.Core assembly. Once loaded add the following code to the file:
</p>
<pre class="brush: csharp;">
#region Using namespaces...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Xml.Linq;
using System.Collections;
using System.IO;
using System.Xml.Xsl;
using System.Xml;
using System.ComponentModel;
#endregion

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// CodeBuilder class
	/// &lt;/summary&gt;
	public class CodeBuilder : MetadataGenerator, INotifyPropertyChanged
	{
		#region Events
		/// &lt;summary&gt;
		/// PropertyChanged event
		/// &lt;/summary&gt;
		public event PropertyChangedEventHandler PropertyChanged;
		#endregion

		#region Members
		/// &lt;summary&gt;
		/// Metadata field
		/// &lt;/summary&gt;
		private string metadata = string.Empty;
		/// &lt;summary&gt;
		/// OutputMessage field
		/// &lt;/summary&gt;
		private string outputMessage = string.Empty;
		#endregion

		#region Properties
		/// &lt;summary&gt;
		/// Gets Metadata
		/// &lt;/summary&gt;
		private string Metadata
		{
			get
			{
				// Retrieve XML
				if (metadata.Equals(string.Empty))
					metadata = GetMetadataXml();
				
				return metadata;
			}
		}

		/// &lt;summary&gt;
		/// Gets/Sets OutputMessage
		/// &lt;/summary&gt;
		public string OutputMessage
		{
			get
			{
				return outputMessage;
			}
			set
			{
				outputMessage = value;

				// Notify of change
				NotifyPropertyChanged(outputMessage);
			}
		}
		#endregion

		#region Constructors
		/// &lt;summary&gt;
		/// Default class constructor
		/// &lt;/summary&gt;
		public CodeBuilder() { }
		#endregion

		#region Utility Methods
		/// &lt;summary&gt;
		/// Handles property change eventing
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;info&quot;&gt;&lt;/param&gt;
		private void NotifyPropertyChanged(String info)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(info));
			}
		}		
		#endregion
	}
}
</pre>
<p>
What we have done here is create the basic skeleton of the class that will be responsible for processing the combined extracted metadata and the XSL template data into useful output that will meet our code generation requirements. As seen in the class signature and class implementation, the CodeBuilder class derives from MetadataGenerator and INotifyPropertyChanged. We derive from MetadataGenerator as a way to maintain the inheritance tree within the classes in the assembly and to provide an in memory persisting mechanism for the retrieved metadata without having to access the generation target database continuously throughout the process of creating our file output. We also implement INotifyPropertyChanged as a way to provide message notifications to the application consuming our assembly about the step the code generation process is engaged in. While this isn't strictly necessary, it is a nice feature to have as it maintains the end user informed about the inner happenings of the component executing within the context of the application. For this purpose, every single time that the string property "OutputMessage" is modified, "NotifyPropertyChanged" is invoked and the "PropertyChanged" event is raised sending whatever message we want to the user about the current executing process.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The Code Generation Process</h2>
<p>
Before we begin writing the necessary code to support code generation against the metadata, we will need a series of support methods and a class that will allow us to write to the file system. We will begin by creating a static public class called "FileSystemUtility". This class will expose two static methods:
</p>
<ul>
	<li>
		CreateDirectory: Will create an output folder and return its path to the caller
	</li>
	<li>
		SaveTransformedSourceToFile: Will parse generated XML and output the content of the "codefile" nodes to the file system
	</li>
</ul>
<p>
At this point you might be thinking: "More XML and codefile nodes?". A brief explanation is in order.  The job of the code generator is to make use of XSL templates that will transform XML metadata belonging to the generation target database. Once the transformation process has completed, the transformed data will be in XML format. The beauty of this approach is that prior to saving and as part of the output to disk, this generated XML data, which contains all of the files we will output, can be queried by using LINQ to XML, ripped apart and saved to files. The following schema represents the output of the XSL transformation against the database we have created on Part I of this code generation series:
</p>
<pre class="brush: xml;">
&lt;codefiles&gt;
	&lt;codefile filename=&quot;&quot;&gt;&lt;![CDATA[ ]]&gt;&lt;/codefile&gt;
&lt;/codefiles&gt;
</pre>
<p>
As seen in the XML schema fragment, all file content will be safely stored within the CDATA section of the "codefile" element, and the generated file name of the resulting file will be stored in the "filename" attribute of the codefile element. Armed with this knowlege, we are ready to begin coding!
</p>
<p>
Add a new static class file to the CodeGenerator.Core assembly and name it "FileSystemUtility". After the class file is added, right-click on the references folder of the assembly and add a reference to the <a href="http://msdn.microsoft.com/en-us/library/system.web.aspx" target="_blank">System.Web</a> assembly. We do this because we will make use of the <a href="http://msdn.microsoft.com/en-us/library/system.web.httputility.htmldecode.aspx" target="_blank">HttpUtility.HtmlDecode</a> method to decode the conversion that occurs during the transformation process of characters into HTML entities. Once done with that step, add the following code to the class:
</p>
<pre class="brush: csharp;">
#region Using namespaces...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Linq;
using System.Web;
#endregion

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// FileSystemHandler class
	/// &lt;/summary&gt;
	static public class FileSystemUtility
	{
		#region Utility Methods
		/// &lt;summary&gt;
		/// Handles the creation of output folders
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;
		static public string CreateDirectory(string outputFolder, FolderTypes folderType)
		{
			// Pre-allocate return value
			string retVal = string.Empty;

			// Create output root folder if it does not exist
			if (!Directory.Exists(outputFolder))
				Directory.CreateDirectory(outputFolder);

			string folderPath = string.Empty;

			// Create output folder
			switch (folderType)
			{
				case FolderTypes.StoredProcedureOutput:
					// Set path
					retVal = Path.Combine(outputFolder, LibraryConstants.FOLDER_NAME_STORED_PROCEDURE);

					// Create folder
					if (!Directory.Exists(retVal))
						Directory.CreateDirectory(retVal);
					break;
			}

			return retVal;
		}

		/// &lt;summary&gt;
		/// Handles saving the transformed XML into separate files to the file system
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;source&quot;&gt;&lt;/param&gt;
		static public void SaveTransformedSourceToFile(string path, byte[] sourceBytes)
		{
			// Build sources from XML
			string stringFromSourceBytes = HttpUtility.HtmlDecode(Encoding.ASCII.GetString(sourceBytes));
			XElement source = XElement.Parse(stringFromSourceBytes, LoadOptions.PreserveWhitespace);

			// Retrieve codefile nodes
			List&lt;XElement&gt; codeFiles = (from elements in source.Descendants(&quot;codefile&quot;) select elements).ToList();

			// Parse result
			foreach (XElement element in codeFiles)
			{
				// Retrieve file name from element attribute
				string fileName = element.Attribute(&quot;filename&quot;).Value;

				// Write file to disk
				if (!string.IsNullOrEmpty(path) &amp;&amp; !string.IsNullOrEmpty(fileName))
				{
					// Create file stream object
					using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                    	// Get data bytes
						byte[] writeData = Encoding.ASCII.GetBytes(element.Value);

						// Flush data to disk
						stream.Write(writeData, 0, writeData.Length);
						stream.Flush();
						stream.Close();
                    }
				}
			}
		}
		#endregion
	}
}

</pre>
<p>
Let's examine the "CreateDirectory" method. This method will receive as a parameter the root output folder path. This is the path were all of our files will be stored. This method however does attempt to organize the output structure by also creating a sub-folder for stored procedures. This method can be further edited to include folders for many more objects as templates are created for more than just stored procedures, but C# and even UI's objects as well. For the purposes of this article however, we will only focus on generating stored procedures. Therefore, this method, though it accept a parameter of FolderTypes type, will only handle FolderTypes.StoredProcedureOutput enumeration members. Essentially, the method will simply combine the path of the output folder with the folder name of the stored procedure folder, create the path if not available, and return the path regardless of whether the path exists or not.
</p>
<p>
Let's now briefly examine the "SaveTransformedSourceToFile" method. This method will accept the path of where the generated files should be saved and a byte array that contains the HTML encoded data that we will be converting back to decoded form and then saving to file. This data, when converted back to a decoded string will look much like the XML schema shown. It is then the responsibility of this method to query the decoded XML string, get the output file name and the codefile node data and then save it to file. There really isn't much more than that to this method and therefore, we can move now to the "CodeBuilder" class that will perform the bulk of the metadata transformation required by the "SaveTransformedSourceToFile" method of the "FileSystemUtility" class.
</p>
<p>
If not already loaded, open up the CodeBuilder class. We will now add a series of support methods to the class that will allow the object to create output folders, create special data tables to store the generated XML output, retrieve XSL template paths, transform output, and act as a single entry point into the code generation process. To do this, we need to add the following methods to the class:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Performs code generation process
/// &lt;/summary&gt;
/// &lt;param name=&quot;templateTypesList&quot;&gt;&lt;/param&gt;
public void PerformCodeGeneration(List&lt;TemplateTypes&gt; templateTypesList)
{
	// Retrieve codeStore
	OutputMessage = &quot;Setting up code store data table...&quot;;
	DataTable codeStore = GetTransformCodeStore(templateTypesList);
	OutputMessage = &quot;Code store data table setup is complete... Preparing to save data&quot;;

	// Process table data
	if (codeStore.Rows.Count &gt; 0)
	{
		OutputMessage = &quot;Processing generated data...&quot;;
		foreach (DataRow row in codeStore.Rows)
		{
			// Create output folder
			string outputPath = CreateOutputFolderIfNotExists((TemplateTypes)row[&quot;TemplateType&quot;]);
			OutputMessage = string.Format(&quot;Created/Verified folder: {0}...&quot;, outputPath);

			// Save files to disk
			OutputMessage = &quot;Preparing to save data to disk...&quot;;
			if (!string.IsNullOrEmpty(outputPath))
				FileSystemUtility.SaveTransformedSourceToFile(outputPath, (byte[])row[&quot;OutputBytes&quot;]);

			OutputMessage = &quot;Successfully saved generated files to disk...&quot;;
		}
	}
}

/// &lt;summary&gt;
/// Handles the creation of the output folder if one does not exist
/// &lt;/summary&gt;
/// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private string CreateOutputFolderIfNotExists(TemplateTypes value)
{
	// Pre-allocate return value
	string retVal = string.Empty;

	// Create output folder
	switch (value)
	{
		case TemplateTypes.StoredProcedureTemplate:
			retVal = FileSystemUtility.CreateDirectory(OutputFolderRoot, FolderTypes.StoredProcedureOutput);
			break;
	}

	return retVal;
}

/// &lt;summary&gt;
/// Returns a data table object that contains transformed data from metadata
/// &lt;/summary&gt;
private DataTable GetTransformCodeStore(List&lt;TemplateTypes&gt; templateTypesList)
{
	// Pre-allocate return value
	DataTable codeStore = null;

	if (templateTypesList.Count &gt; 0)
	{
		// Prepare code store
		codeStore = GetCodeStore();

		// Process template types
		OutputMessage = &quot;Retrieving templates...&quot;;
		foreach (TemplateTypes templateType in templateTypesList)
		{
			// Retrieve template paths from configuration
			Dictionary&lt;string, string&gt; templatePaths = GetTemplatePaths(templateType);
			OutputMessage = &quot;Successfully built template dictionary...\n&quot;;

			// Parse templates
			foreach (string key in templatePaths.Keys)
			{
				OutputMessage = string.Format(&quot;Verifyting {0} template...&quot;, key);
				if (File.Exists(templatePaths[key]))
				{
					// Create new row with values
					OutputMessage = &quot;Template verified, proceeding to transform output...&quot;;
					DataRow row = codeStore.NewRow();
					row[&quot;TemplateType&quot;] = templateType;
					row[&quot;OutputBytes&quot;] = Encoding.ASCII.GetBytes(TransformedOutput(templatePaths[key]));

					// Add row to code store
					codeStore.Rows.Add(row);
				}
			}
		}
	}

	return codeStore;
}

/// &lt;summary&gt;
/// 
/// &lt;/summary&gt;
/// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private DataTable GetCodeStore()
{
	// Pre-allocate return value
	DataTable retVal = new DataTable(&quot;CodeStore&quot;);

	// Load columns
	retVal.Columns.Add(new DataColumn(&quot;TemplateType&quot;, typeof(TemplateTypes)));
	retVal.Columns.Add(new DataColumn(&quot;OutputBytes&quot;, typeof(byte[])));

	return retVal;
}

/// &lt;summary&gt;
/// Returns a transformed version of the metadata
/// &lt;/summary&gt;
/// &lt;param name=&quot;templatePath&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private string TransformedOutput(string templatePath)
{
	// Create transform object and load template
	OutputMessage = string.Format(&quot;Loading {0}...&quot;, templatePath);
	XslCompiledTransform transform = new XslCompiledTransform(false);
	transform.Load(templatePath);

	// Create the XML reader that will contain the XML metadata extracted from the server
	XmlReader xmlReader = XmlReader.Create(new StringReader(Metadata));

	// Create XML writer settings
	XmlWriterSettings settings = new XmlWriterSettings();
	settings.CloseOutput = true;
	settings.ConformanceLevel = ConformanceLevel.Fragment;
	

	// Create the XML writer that will create the output of the XSL transformation
	StringBuilder retVal = new StringBuilder();
	XmlWriter xmlWriter = XmlWriter.Create(retVal, settings);

	// Transform the metadata into the target code object
	OutputMessage = string.Format(&quot;Generating items for {0}...&quot;, templatePath);
	transform.Transform(xmlReader, xmlWriter);
	OutputMessage = &quot;SUCCESS!...\n&quot;;

	return retVal.ToString();
}

/// &lt;summary&gt;
/// Retrieves template paths
/// &lt;/summary&gt;
/// &lt;param name=&quot;value&quot;&gt;&lt;/param&gt;
/// &lt;returns&gt;&lt;/returns&gt;
private Dictionary&lt;string, string&gt; GetTemplatePaths(TemplateTypes value)
{
	// Pre-allocate return value
	Dictionary&lt;string, string&gt; retVal = new Dictionary&lt;string, string&gt;();

	// Parse template types
	switch (value)
	{
		case TemplateTypes.StoredProcedureTemplate:
			retVal.Add(&quot;SelectProcedure&quot;, SelectProcedureTemplatePath);
			break;
	}

	return retVal;
}
</pre>
<p>
The following table explains what each method does:
</p>
<table cellpading="2" cellspacing="0" width="100%" style="border: 1px solid silver;">
	<tr>
		<td style="width: 100px; font-weight: bold;">
			CreateOutputFolderIfNotExists	
		</td>
		<td>
			This method receives a TemplateType value that in turn, it translates form the purpose of calling the FileSystemUtility.CreateDirectory() method and returning the final output folder for the generated file.
		</td>
	</tr>
	<tr>
		<td style="width: 100px; font-weight: bold;">
			GetCodeStore	
		</td>
		<td>
			This method is responsible for creating a blank table with two columns:
			<ul>
				<li>
					A column for the template type.
				</li>
				<li>
					A column for the transformation output in binary form.
				</li>
			</ul>
		</td>
	</tr>
	<tr>
		<td style="width: 100px; font-weight: bold;">
			GetTemplatePaths
		</td>
		<td>
			This method accepts a value of TemplateTypes type and in turn returns a dictionary containing the paths of the target templates as exposed by the CoreBase class.	
		</td>
	</tr>
	<tr>
		<td style="width: 100px; font-weight: bold;">
			TransformedOutput
		</td>
		<td>
			This method is primarily responsible for transforming XML metadata into generated code.
		</td>
	</tr>
	<tr>
		<td style="width: 100px; font-weight: bold;">
			GetTransformCodeStore
		</td>
		<td>
			This method populates the data table that contains the generated code in XML format to be parsed by the FileSystemUtility class.	
		</td>
	</tr>
	<tr>
		<td style="width: 100px; font-weight: bold;">
			PerformCodeGeneration
		</td>
		<td>
			This is the only method that will interact with a calling application. This could be considered the entry point in the code generation process managed by the CodeBuilder class. It accepts a generic list of type "TemplateTypes" that will be passed down to the GetTransformCodeStore() method. For each template type, the class generates requested code.	
		</td>
	</tr>
</table>
<p>
While brief, the previous walkthroughs through the CodeBuilder class provide insight in how the code generation process works. Now that the CodeGenerator.Core assembly is complete, a quick class diagram of all classes in the assembly should resemble the following:
</p>
<div id="attachment_107" class="wp-caption alignnone" style="width: 442px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/06/codegeneratorpart2classdiagram.png" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/06/codegeneratorpart2classdiagram.png" alt="CodeGenerator.Core Class Diagram" title="CodeGenerator.Core Class Diagram" width="432" height="648" class="size-full wp-image-107" /></a><p class="wp-caption-text">CodeGenerator.Core Class Diagram</p></div>
<p>
Next, we will create a basic template for a stored procedure that will be responsible for selecting all rows from a database table (the generation target database). 
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">A Simple Template</h2>
<p>
Before continuing, while this article only covers the creation of one template, the available source code for this article does contain templates for the following stored procedures
<p/>
<ul>
	<li>
		Delete Procedure
	</li>
	<li>
		Insert Procedure
	</li>
	<li>
		Search Procedure
	</li>
	<li>
		Select Procedure
	</li>
	<li>
		Update Procedure
	</li>
</ul>
<p>
Also, it is not the intention of this article to be a tutorial on XSL programming. The template code is provided "as is" and simply because without templates, the application would not work so well. Disclaimers aside, the templates will follow a very specific structure that conforms to the metadata we have obtained from the generation target database. The templates will perform the following tasks:
</p>
<ul>
	<li>
		Find the root of the metadata XML document 
	</li>
	<li>
		Create a series of variables to be used as shortcuts throughout the template	
	</li>
	<li>
		Iterate through the table elements of the metadata document	
	</li>
	<li>
		Create the file name of the destination file	
	</li>
	<li>
		Insert heading information which will include personalization data if specified to be used		
	</li>
	<li>
		Create the structure of the file	
	</li>
</ul>
<p>
The following is a sample "Select All" type stored procedure template made to work with our metadata:
</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
&lt;xsl:output method=&quot;text&quot; /&gt;
&lt;xsl:template match=&quot;/metadata&quot;&gt;

&lt;!-- 
	Template Type: Select Stored Procedure
	Template Version: 1.0
	Created: 6/04/2009
--&gt;

&lt;!-- Global Variable Declarations --&gt;
&lt;xsl:variable name=&quot;databaseName&quot; select=&quot;project/@database&quot; /&gt;
&lt;xsl:variable name=&quot;creationDate&quot; select=&quot;project/@created&quot; /&gt;
&lt;xsl:variable name=&quot;namePrefix&quot; select=&quot;project/@sqlcodeobjectprefix&quot; /&gt;
&lt;xsl:variable name=&quot;usePersonalData&quot; select=&quot;project/personalization/@includepersonaldata&quot; /&gt;
&lt;xsl:variable name=&quot;developerName&quot; select=&quot;project/personalization/developername&quot; /&gt;
&lt;xsl:variable name=&quot;companyName&quot; select=&quot;project/personalization/company&quot; /&gt;
&lt;xsl:variable name=&quot;developerPosition&quot; select=&quot;project/personalization/position&quot; /&gt;
&lt;xsl:variable name=&quot;developerURL&quot; select=&quot;project/personalization/developerurl&quot; /&gt;
&lt;xsl:variable name=&quot;copyrightInformation&quot; select=&quot;project/personalization/copyright&quot; /&gt;

&lt;!-- Object Header Information --&gt;
&lt;!-- --&gt;&amp;#60;codefiles&amp;#62;
&lt;xsl:for-each select=&quot;project/databasetables/table&quot;&gt;
&lt;xsl:variable name=&quot;objectName&quot; select=&quot;@name&quot; /&gt;
&lt;xsl:variable name=&quot;objectType&quot; select=&quot;@type&quot; /&gt;
&lt;xsl:variable name=&quot;parentObjectPrimaryKey&quot; select=&quot;columns/column[@primarykeystatus='true']/@name&quot; /&gt;
&lt;xsl:if test=&quot;$objectType='table'&quot;&gt;
&lt;!-- --&gt;&amp;#60;codefile filename=&quot;&lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select.sql&quot;&amp;#62;&amp;#60;![CDATA[
/******************************************************************************
** Source Database: &lt;xsl:value-of select=&quot;$databaseName&quot; /&gt;
** Object Name: &lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select
** Creation Date: &lt;xsl:value-of select=&quot;$creationDate&quot; /&gt;
&lt;xsl:if test=&quot;$usePersonalData='true'&quot;&gt;
** Developer Name: &lt;xsl:value-of select=&quot;$developerName&quot; /&gt;
** Company Name: &lt;xsl:value-of select=&quot;$companyName&quot; /&gt;
** Position: &lt;xsl:value-of select=&quot;$developerPosition&quot; /&gt;
** URL: &lt;xsl:value-of select=&quot;$developerURL&quot; /&gt;
** Copyrignt Information: &lt;xsl:value-of select=&quot;$copyrightInformation&quot; /&gt;
** Legal:
** This source code is protected by the copyright laws of the United States of 
** America and international treaties. Any unauthorized reproduction and/or
** distribution of this source code is strictly prohibited.
&lt;/xsl:if&gt;
&lt;!-- --&gt;******************************************************************************/

IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = '&lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select')
	BEGIN
		PRINT 'Dropping Procedure &lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select'
		DROP  Procedure  [&lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select]
	END

GO

PRINT 'Creating Procedure &lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select'
GO

CREATE PROCEDURE dbo.[&lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Select]
AS

-- Disable affected record count
SET NOCOUNT ON

-- Select all data from &lt;xsl:value-of select=&quot;$objectName&quot; /&gt; and order by primary key
SELECT * FROM [&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;] ORDER BY &lt;xsl:value-of select=&quot;$parentObjectPrimaryKey&quot; /&gt;
GO

GRANT EXEC ON [&lt;xsl:value-of select=&quot;$namePrefix&quot; /&gt;_&lt;xsl:value-of select=&quot;$objectName&quot; /&gt;_Update] TO public
GO]]&amp;#62;&amp;#60;/codefile&amp;#62;
&lt;/xsl:if&gt;
&lt;/xsl:for-each&gt;
&lt;!-- --&gt;&amp;#60;/codefiles&amp;#62;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
</pre>
<p>
While it may seem like a tedious task (and I often believe it is) to code these templates, the silver lining is that they only have to be coded once and simply used. If well documented, these templates are fairly simple to maintain as requirements for such templates change over time. Having now covered template structure all we have left to do is modify the CodeGenerator console application to make use of the assembly  and template we have completed
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Putting X, Y, Z to Work Together</h2>
<p>
It is finally time to finish the application and start generating code files. To do so, we will need to modify the Program class on the CodeGenerator console application. Load the file and add the following code to the Main() method of the class:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Main application entry method
/// &lt;/summary&gt;
/// &lt;param name=&quot;args&quot;&gt;&lt;/param&gt;
static void Main(string[] args)
{
	// Signal start of code generation process
	Console.ForegroundColor = ConsoleColor.Green;
	Console.WriteLine(&quot;Starting code generation process: {0}&quot;.ToUpper(), 
		DateTime.Now.ToString());

	// Create list of templates to process
	List&lt;TemplateTypes&gt; templatesToProcess = new List&lt;TemplateTypes&gt;();
	templatesToProcess.Add(TemplateTypes.StoredProcedureTemplate);

	// Create code builder and generate code
	Console.ForegroundColor = ConsoleColor.DarkGray;
	Console.WriteLine(&quot;\nStarting code generation process...&quot;);
	CodeBuilder builder = new CodeBuilder();
	builder.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(builder_PropertyChanged);

	builder.PerformCodeGeneration(templatesToProcess);

	// Signal completion
	Console.ForegroundColor = ConsoleColor.Green;
	Console.WriteLine(&quot;\nCode generation process is complete: {0}&quot;.ToUpper(), 
		DateTime.Now.ToString());

	// Hang the console
	Console.ForegroundColor = ConsoleColor.DarkGray;
	Console.WriteLine(&quot;\n\nPress [Return] to exit...&quot;);
	Console.Read();
}
</pre>
<p>
The code simply creates a list of TemplateTypes type and invokes the PerformCodeGeneration method passing the template types list along to the CodeGenerator.Core assembly. Also, as noted in the Main method with the line:
</p>
<pre class="brush: csharp;">
builder.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(builder_PropertyChanged);
</pre>
<p>
we will need to add a static method that will handle messaging to the screen for the application as part of the "INotifyPropertyChanged" implementation of the CodeBuilder class. Therefore, add the following method to the Program class:
</p>
<pre class="brush: csharp;">
/// &lt;summary&gt;
/// Handles PropertyChanged events
/// &lt;/summary&gt;
/// &lt;param name=&quot;sender&quot;&gt;&lt;/param&gt;
/// &lt;param name=&quot;e&quot;&gt;&lt;/param&gt;
static void builder_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
	// Output message to the console
	Console.WriteLine(e.PropertyName);
}
</pre>
<p>
At this point, we are ready to build the application and launch it. If things go well, the application will display a series of messages to the screen and created the necessary output folders specified in the configuration file and all of generated files supported by the provided templates. 
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Conclusion</h2>
<p>
In this Code Generation series we have explored the concepts behind code generation and the tools that are available for free to make this task a possibility without having to commit to non-free and rather expensive applications available commercially. While these applications are excellent choices for their intended purpose, their purpose can indeed be achieved by simple means and moderate programming skill while maintaining full control over patterns, design and architecture. 
</p>


<p>
	Get the <a href='http://www.pcsweblabs.com/wp-content/uploads/2009/06/codegeneratorpart2.zip'>source code</a> for this article.
</p>

        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <div style="width: auto; border: 1px solid silver; margin-top: 10px;"><div style="width: auto; padding: 2px; border-bottom: 1px solid silver; background-color: #F7F7F7; font-weight: bold;">Donations</div><div style="padding: 4px;"><input type="hidden" name="business" value="raytristani@gmail.com" /><input type="hidden" name="item_name" value="Donation" /><input type="hidden" name="currency_code" value="USD" /><label style="display: block; margin: 2px;">Show your support to the authors of this site. Your donation is greatly appreciated.</label><input type="image" src="http://www.pcsweblabs.com/wp-content/plugins/wp-simple-paypal-donation/btn_donate_LG.gif" name="submit" alt="Show your support to the authors of this site. Your donation is greatly appreciated." /></div></div></form>]]></content:encoded>
			<wfw:commentRss>http://www.pcsweblabs.com/index.php/2009/06/06/code-generation-creating-a-code-generator-with-c-xml-and-xslt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Generation Part I &#8211; Extract Database Metadata</title>
		<link>http://www.pcsweblabs.com/index.php/2009/05/29/code-generation-extract-database-metadata/</link>
		<comments>http://www.pcsweblabs.com/index.php/2009/05/29/code-generation-extract-database-metadata/#comments</comments>
		<pubDate>Fri, 29 May 2009 07:17:57 +0000</pubDate>
		<dc:creator>ramon_tristani</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Code Generation]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[Console Application]]></category>
		<category><![CDATA[Data]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Metadata]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[Source Code]]></category>
		<category><![CDATA[SQL Server]]></category>
		<category><![CDATA[XSL]]></category>
		<category><![CDATA[XSLT]]></category>

		<guid isPermaLink="false">http://www.pcsweblabs.com/?p=9</guid>
		<description><![CDATA[Overview [inline][/inline] This article is the first in a series of code generation articles that will demonstrate the basic concepts of using code and freely available tools to generate code and eliminate hours of tedious and repetitive work. We will in addition, demonstrate how code generation may be used to create consistent code based on [...]]]></description>
			<content:encoded><![CDATA[<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Overview</h2>
[inline][/inline]
<p>
This article is the first in a series of code generation articles that will demonstrate the basic concepts of using code and freely available tools to generate code and eliminate hours of tedious and repetitive work. We will in addition, demonstrate how code generation may be used to create consistent code based on architectural patterns. Instead of presenting all of the concepts involved in code generation all at once, we will peacemeal these concepts into major functional areas. These are:
</p>
<ul>
	<li>Extraction of database metadata <strong>without</strong> the use of SQLDMO or its .NET counterpart SMO</li>
	<li>Using LINQ to XML to format all extracted metadata</li>
	<li>Using XSLT to generate code on the fly</li>
	<li>Using what we've learned with design patterns</li>
</ul>
<span id="more-9"></span>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Data About Data</h2>
<p>
Before any code generation can take place, it is very important to obtain as much information about the data store we are trying to generate code for. This descriptive metadata, or "data about data" is at the heart of our code generation process. For the purposes of this article, we will be using <a href="http://www.microsoft.com/servers/sql/2008/sqlserverenergy/en/us/default.aspx?WT.mc_id=E1807F95-5A28-445B-B961-70F4D4EC9F29&WT.srch=1" target="_blank">Microsoft SQL Server 2008</a> as our database engine. The concepts discussed in this article could be applied to other database engines as long as specific metadata extraction methodologies, specific to that engine, are used.
</p>
<p>
Before we go any further however, some friendly advice about naming conventions and style is in order. In this article, as well as any other article or project, <strong>Pascal Notation</strong> is used, <strong>NOT</strong> Hungarian Notation. For a comparison and stylistic differences, please refer to  
<a href="http://www.akadia.com/services/naming_conventions.html" target="_blank">Naming Conventions for .NET / C# Projects</a>. Adhering to these conventions will make our resulting code more elegant, descriptive, and natural. The importance of this will become more apparent as we move forward.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">First Steps</h2>
<p>
Now that we have a basic understanding of our requirements, we can now begin by creating our database. For the purpose of this article, a very simple database was created called "CodeGeneration". This is our first step, so please load SQL Server Management Studio and create this database. Use the following SQL script to create the schema by loading a new script editor ensuring that the CodeGeneration database is selected first:
</p>
<pre class="brush: sql;">
USE [CodeGeneration]
GO
/****** Object:  Table [dbo].[Gender] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Gender](
	[GenderID] [int] IDENTITY(1,1) NOT NULL,
	[Type] [nvarchar](50) NOT NULL,
	[Created] [datetime] NOT NULL,
	[Updated] [datetime] NOT NULL,
	[IsActive] [bit] NOT NULL,
	[Description] [nvarchar](512) NOT NULL,
 CONSTRAINT [PK_Gender] PRIMARY KEY CLUSTERED 
(
	[GenderID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Person] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Person](
	[PersonID] [int] IDENTITY(1,1) NOT NULL,
	[GenderID] [int] NOT NULL,
	[FullName] [nvarchar](50) NOT NULL,
	[Age] [int] NOT NULL,
	[Created] [datetime] NOT NULL,
	[Updated] [datetime] NOT NULL,
	[IsActive] [bit] NOT NULL,
	[Description] [nvarchar](512) NOT NULL,
 CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED 
(
	[PersonID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Email] ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Email](
	[EmailID] [int] IDENTITY(1,1) NOT NULL,
	[PersonID] [int] NOT NULL,
	[Email] [nvarchar](50) NOT NULL,
	[Created] [datetime] NOT NULL,
	[Updated] [datetime] NOT NULL,
	[IsActive] [bit] NOT NULL,
	[Description] [nvarchar](512) NOT NULL,
 CONSTRAINT [PK_Email] PRIMARY KEY CLUSTERED 
(
	[EmailID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Default [DF_Email_Created] ******/
ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_Created]  DEFAULT (getdate()) FOR [Created]
GO
/****** Object:  Default [DF_Email_Updated] ******/
ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_Updated]  DEFAULT (getdate()) FOR [Updated]
GO
/****** Object:  Default [DF_Email_IsActive] ******/
ALTER TABLE [dbo].[Email] ADD  CONSTRAINT [DF_Email_IsActive]  DEFAULT ((1)) FOR [IsActive]
GO
/****** Object:  Default [DF_Gender_Created] ******/
ALTER TABLE [dbo].[Gender] ADD  CONSTRAINT [DF_Gender_Created]  DEFAULT (getdate()) FOR [Created]
GO
/****** Object:  Default [DF_Gender_Updated] ******/
ALTER TABLE [dbo].[Gender] ADD  CONSTRAINT [DF_Gender_Updated]  DEFAULT (getdate()) FOR [Updated]
GO
/****** Object:  Default [DF_Gender_IsActive] ******/
ALTER TABLE [dbo].[Gender] ADD  CONSTRAINT [DF_Gender_IsActive]  DEFAULT ((1)) FOR [IsActive]
GO
/****** Object:  Default [DF_Person_Created] ******/
ALTER TABLE [dbo].[Person] ADD  CONSTRAINT [DF_Person_Created]  DEFAULT (getdate()) FOR [Created]
GO
/****** Object:  Default [DF_Person_Updated] ******/
ALTER TABLE [dbo].[Person] ADD  CONSTRAINT [DF_Person_Updated]  DEFAULT (getdate()) FOR [Updated]
GO
/****** Object:  Default [DF_Person_IsActive] ******/
ALTER TABLE [dbo].[Person] ADD  CONSTRAINT [DF_Person_IsActive]  DEFAULT ((1)) FOR [IsActive]
GO
/****** Object:  ForeignKey [FK_Email_Person] ******/
ALTER TABLE [dbo].[Email]  WITH CHECK ADD  CONSTRAINT [FK_Email_Person] FOREIGN KEY([PersonID])
REFERENCES [dbo].[Person] ([PersonID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Email] CHECK CONSTRAINT [FK_Email_Person]
GO
/****** Object:  ForeignKey [FK_Person_Gender] ******/
ALTER TABLE [dbo].[Person]  WITH CHECK ADD  CONSTRAINT [FK_Person_Gender] FOREIGN KEY([GenderID])
REFERENCES [dbo].[Gender] ([GenderID])
GO
ALTER TABLE [dbo].[Person] CHECK CONSTRAINT [FK_Person_Gender]
GO

</pre>
<p>
Once the script is executed against the CodeGeneration database, create a new database diagram and add all of the database tables. When that step is complete, you should end up with a model that is similar to the following:
</p>
<div id="attachment_40" class="wp-caption alignnone" style="width: 400px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/05/codegenerationdatamodel.png" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/05/codegenerationdatamodel.png" alt="Code Generation Data Model" title="Code Generation Data Model" width="390" height="460" class="size-full wp-image-40" /></a><p class="wp-caption-text">Code Generation Data Model</p></div>
<p>
The database model was purposely made simple in an effort to maintain focus and march straight to our goal of extracting database metadata and storing it in XML format. Having now completed this step, we are now ready to move forward.
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Building Blocks</h2>
<p>
Now that we have a database to work with, we can now begin to create the code generator application. In keeping with tradition, we will build a simple code generator with a Console Application. This application will in turn make use of an utility assembly that will contain all of the necessary functionality to extract metadata from the database and translate that metadata into useful code objects. This assembly will assume the role of the code generation engine. Let's get started!
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">CodeGenerator.Core</h2>
<p>
If you haven't done so already, load Visual Studio and create a new empty solution named "Code Generation Tutorial" or anything that you like. Once we have a solution, add a new C# project of type "Class Library" and name it "CodeGenerator.Core" without the quotes. Once created, delete the "Class1.cs" default class as we will be adding our own classes. Since the code generator will rely on a configuration file at a later point in time, go ahead and add a reference to the <a href="http://msdn.microsoft.com/en-us/library/system.configuration.aspx" target="_blank">System.Configuration</a> assembly to our project. We do this because much of the information the code generator will require at runtime, such as server instance name, connection strings, code decoration information, will be stored in a configuration file that we can modify on the fly. It is important to note that just as any other commercially available code generation utility, the application will need to make use of many different configurations and database targets. Therefore, it is recognized that using a single configuration file is probably not the best approach. Given that we are sticking to simplicity however, this approach will be used instead of a more robust configuration management scheme.
</p>
<p>
The first coding step we will take will be to create a class that will contain a series of string constants. These constants will represent stored procedure names and configuration key names. We do this to avoid or limit the use of "magic strings" in our code.Let's get started. Add a static class to the CodeGenerator.Core project named LibraryConstants.cs and add the following code:
</p>
<pre class="brush: csharp;">
namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// LibraryConstants class
	/// &lt;/summary&gt;
	static public class LibraryConstants
	{
		/// &lt;summary&gt;
		/// Master database connection string configuration key
		/// &lt;/summary&gt;
		public const string MASTER_DATABASE_CONNECTION_KEY = &quot;MasterDatabaseConnectionString&quot;;
		/// &lt;summary&gt;
		/// Target database connection string configuration key
		/// &lt;/summary&gt;
		public const string TARGET_DATABASE_CONNECTION_KEY = &quot;CodeGeneration&quot;;
		/// &lt;summary&gt;
		/// Target database configuration key
		/// &lt;/summary&gt;
		public const string TARGET_DATABASE_KEY = &quot;TargetDatabase&quot;;
		/// &lt;summary&gt;
		/// SQL Server instance configuration key
		/// &lt;/summary&gt;
		public const string SQL_SERVER_INSTANCE_KEY = &quot;SqlServerInstance&quot;;		
		/// &lt;summary&gt;
		/// Help server stored procedure
		/// &lt;/summary&gt;
		public const string HELP_SERVER_SPROC = &quot;sp_helpserver&quot;;
		/// &lt;summary&gt;
		/// Databases stored procedure
		/// &lt;/summary&gt;
		public const string INSTANCE_DATABASES_SPROC = &quot;sp_databases&quot;;
		/// &lt;summary&gt;
		/// Primary keys procedure
		/// &lt;/summary&gt;
		public const string P_KEYS_SPROC = &quot;sp_pkeys&quot;;
		/// &lt;summary&gt;
		/// Foreign keys procedure
		/// &lt;/summary&gt;
		public const string F_KEYS_SPROC = &quot;sp_fkeys&quot;;
		/// &lt;summary&gt;
		/// Columns procedure
		/// &lt;/summary&gt;
		public const string COLUMNS_SPROC = &quot;sp_columns&quot;;
		/// &lt;summary&gt;
		/// Database tables stored procedure
		/// &lt;/summary&gt;
		public const string DATABASE_TABLES_SPROC = &quot;sp_tables&quot;;
		/// &lt;summary&gt;
		/// Include personalization key
		/// &lt;/summary&gt;
		public const string INCLUDE_PERSONALIZATION_KEY = &quot;IncludePersonalization&quot;;
		/// &lt;summary&gt;
		/// Developer name key
		/// &lt;/summary&gt;
		public const string DEVELOPER_NAME_KEY = &quot;DeveloperName&quot;;
		/// &lt;summary&gt;
		/// Developer company key
		/// &lt;/summary&gt;
		public const string DEVELOPER_COMPANY_KEY = &quot;Company&quot;;
		/// &lt;summary&gt;
		/// Developer position key
		/// &lt;/summary&gt;
		public const string DEVELOPER_POSITION_KEY = &quot;Position&quot;;
		/// &lt;summary&gt;
		/// Developer URL key
		/// &lt;/summary&gt;
		public const string DEVELOPER_URL_KEY = &quot;DeveloperUrl&quot;;
		/// &lt;summary&gt;
		/// Copyright key
		/// &lt;/summary&gt;
		public const string COPYRIGHT_KEY = &quot;Copyright&quot;;
	}
}
</pre>
<p>
Don't worry about what each of these constans mean for now. While their meaning is somewhat explained by the comments in the code, their usage will become more aparent later in this article. We will next create a base class that will contain some important properties we will need. This base class will essentially wrap "AppSettings" elements from the main configuration file that we will add to the code generator application. Add an anstract class to the project named CoreBase.cs and add the following code to it:
<p/>
<pre class="brush: csharp;">
using System.Configuration;

namespace CodeGenerator.Core
{
	public abstract class CoreBase
	{
		#region Properties
		/// &lt;summary&gt;
		/// Gets MasterDatabaseConnectionString
		/// &lt;/summary&gt;
		protected string MasterDatabaseConnectionString
		{
			get
			{
				return ConfigurationManager
					.ConnectionStrings[LibraryConstants.MASTER_DATABASE_CONNECTION_KEY]
					.ConnectionString;
			}
		}
		/// &lt;summary&gt;
		/// Gets TargetDatabase
		/// &lt;/summary&gt;
		protected string TargetDatabaseConnectionString
		{
			get
			{
				return ConfigurationManager
					.ConnectionStrings[LibraryConstants.TARGET_DATABASE_CONNECTION_KEY]
					.ConnectionString;
			}
		}
		/// &lt;summary&gt;
		/// Gets SqlServerInstance
		/// &lt;/summary&gt;
		protected string SqlServerInstance
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.SQL_SERVER_INSTANCE_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets TargetDatabase
		/// &lt;/summary&gt;
		protected string TargetDatabase
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.TARGET_DATABASE_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets IncludePersonalization
		/// &lt;/summary&gt;
		protected string IncludePersonalization
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.INCLUDE_PERSONALIZATION_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets DeveloperName
		/// &lt;/summary&gt;
		protected string DeveloperName
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.DEVELOPER_NAME_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets Company
		/// &lt;/summary&gt;
		protected string Company
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.DEVELOPER_COMPANY_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets Position
		/// &lt;/summary&gt;
		protected string Position
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.DEVELOPER_POSITION_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets DeveloperUrl
		/// &lt;/summary&gt;
		protected string DeveloperUrl
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.DEVELOPER_URL_KEY];
			}
		}
		/// &lt;summary&gt;
		/// Gets Copyright
		/// &lt;/summary&gt;
		protected string Copyright
		{
			get
			{
				return ConfigurationManager.AppSettings[LibraryConstants.COPYRIGHT_KEY];
			}
		}
		#endregion
	}
}
</pre>
<p>
As seen in the CoreBase class, we are making use of the constants in the LibraryConstants class to identify sections in a future App.config file. Doing this, we now have a clearer idea as to what this file will look like. The App.config file will contain information that will be used for the identification of the target database, server instance, developer information, etc.
</p>
<p>
One aspect of metadata retrieval that is of great importance is the ability to validate the availability of not just the SQL Server instance, but the existance of the database itself. We can achieve this in many ways such as
</p>
<ol>
	<li>Using SMO or SQLDMO</li>
	<li>Opening a SQLConnection with a connection string and test for exceptions</li>
	<li>or, query SQL Server itself using system procedures to get at the validation data we need</li>
</ol>
<p>
While the second option might seem as the most natural and quickest of all the mentioned options, it is part of the intention of this article to expose the functionality of these specialized system procedures. Therefore, it is for this reason that the first two options will not be used in this tutorial, though they are indeed worth mentioning and perhaps even explored in future articles. 
</p>
<p>
For the purpose of validating what we shall call the "generation target", we will be creating a class that will inherit CoreBase directly. Indirectly however, it is worth mentioning before hand that every class within the CodeGenerator.Core assembly will directly or indirectly inherit CoreBase; with the notable exception of LibraryConstans. Add a class to the project and call this class DataSourceValidator and have this class inherit from CoreBase. Add the following code to the class:
</p>
<pre class="brush: csharp;">
using System;
using System.Data;
using System.Data.SqlClient;

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// DataSourceValidator class
	/// &lt;/summary&gt;
	public class DataSourceValidator : CoreBase
	{
		#region Constructor
		/// &lt;summary&gt;
		/// Default constructor
		/// &lt;/summary&gt;
		public DataSourceValidator() { }
		#endregion
		
		#region Utility Methods
		/// &lt;summary&gt;
		/// Indicates whether a data store is valid
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;serverInstance&quot;&gt;&lt;/param&gt;
		/// &lt;param name=&quot;databaseName&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		public bool IsValidTarget()
		{
			// Allocate default return value
			bool retVal = false;

			try
			{
				retVal = ServerIsValid() &amp;&amp; DatabaseIsValid();
			}
			catch
			{
				// Do nothing - Simply return default value
			}

			return retVal;
		}

		/// &lt;summary&gt;
		/// Indicates whether the server instance is valid or not
		/// &lt;/summary&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		private bool ServerIsValid()
		{
			// Allocate default return value
			bool retVal = false;

			// Begin server validation process
			using (DataSet availableServers = new DataSet(&quot;AvailableServers&quot;))
            {
				// Connect to the master database
            	using (SqlConnection connection = new SqlConnection(MasterDatabaseConnectionString))
                {
                	// Fetch all servers
					using (SqlCommand retrieveServers = new SqlCommand(LibraryConstants.HELP_SERVER_SPROC, connection))
                    {
						// Set up data adapter
                    	using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveServers))
                        {
                        	// Set command type and fill the dataset
							retrieveServers.CommandType = CommandType.StoredProcedure;
							adapter.Fill(availableServers);

							// Begin server instance validation
							if (availableServers.Tables.Count &gt; 0)
							{
								// Get rows that match the instance name
								DataRow[] rows = availableServers.Tables[0].Select(string.Format(&quot;name='{0}'&quot;, SqlServerInstance));

								// Set return value
								if (rows.Length &gt; 0)
									retVal = rows[0][&quot;name&quot;].ToString().ToLower().Equals(SqlServerInstance.ToLower());
							}
                        }
                    }
                }
            }

			return retVal;
		}

		/// &lt;summary&gt;
		/// Indicates whether the database is valid or not
		/// &lt;/summary&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		private bool DatabaseIsValid()
		{
			// Allocate default return value
			bool retVal = false;

			// Begin database validation process
			using (DataSet availableDatabases = new DataSet(&quot;AvailableDatabases&quot;))
			{
				// Connect to the master database
				using (SqlConnection connection = new SqlConnection(MasterDatabaseConnectionString))
				{
					// Fetch all databases
					using (SqlCommand retrieveDatabases = new SqlCommand(LibraryConstants.INSTANCE_DATABASES_SPROC, connection))
					{
						// Set up data adapter
						using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveDatabases))
						{
							// Set command type and fill the dataset
							retrieveDatabases.CommandType = CommandType.StoredProcedure;
							adapter.Fill(availableDatabases);

							// Begin server instance validation
							if (availableDatabases.Tables.Count &gt; 0)
							{
								// Get rows that match the instance name
								DataRow[] rows = availableDatabases.Tables[0].Select(string.Format(&quot;DATABASE_NAME='{0}'&quot;, TargetDatabase));

								// Set return value
								if (rows.Length &gt; 0)
									retVal = rows[0][&quot;DATABASE_NAME&quot;].ToString().ToLower().Equals(TargetDatabase.ToLower());
							}
						}
					}
				}
			}

			return retVal;
		}
		#endregion
	}
}
</pre>
<p>
As seen in the code to this point, the DataSourceValidator class consists of three methods. Two private methods: DatabaseIsValid() and ServerIsValid(); are wrapped inside of the public method IsValidTarget() which will return the combined validation result of the forementioned methods. Again notice how these methods make use of the LibraryConstants constants in order to minimize the usage of "magic strings" throughout our code. Additionally, these methods make use of system procedures to retrieve SQL Server instances and databases in order to validate our future entries in the App.config file later on and do provide a template of sorts of what our calls will look like against the generation target.
</p>
<p>
The next step will be to create another abstract class named TargetSchemaInfo that will also inherit from CoreBase to our project. This class will contain some very important pieces that will be used by a derived class named MetadataGenerator for the collection of database tables, child tables, columns, primary key columns, connections to the generation target, etc. Once the class has been added and made to inherit from CoreBase, add the following code to it:
</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.SqlClient;

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// TargetSchemaInfo class
	/// &lt;/summary&gt;
	public abstract class TargetSchemaInfo : CoreBase
	{
		#region Properties
		/// &lt;summary&gt;
		/// Gets/Sets Connection
		/// &lt;/summary&gt;
		protected SqlConnection Connection { get; set; }
		#endregion

		#region Constructor
		/// &lt;summary&gt;
		/// Default constructor
		/// &lt;/summary&gt;
		public TargetSchemaInfo() : base() 
		{
			// Initialize object
			Initialize();
		}
		#endregion

		#region Utility Methods
		/// &lt;summary&gt;
		/// Handles class initialization logic
		/// &lt;/summary&gt;
		private void Initialize()
		{
			// Create validator
			DataSourceValidator validator = new DataSourceValidator();

			if (validator.IsValidTarget())
			{
				// Initialize and open connection to the target database
				Connection = new SqlConnection(TargetDatabaseConnectionString);
				Connection.Open();
			}
		}
		
		/// &lt;summary&gt;
		/// Retrieves a list of database tables in the target database
		/// &lt;/summary&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		protected List&lt;string&gt; DatabaseTables()
		{
			// Pre-allocate return value
			List&lt;string&gt; retVal = new List&lt;string&gt;();

			// Begin process of fetching database tables
			using (DataSet availableTables = new DataSet(&quot;AvailableTables&quot;))
			{
				using (SqlCommand retrieveTables = new SqlCommand(LibraryConstants.DATABASE_TABLES_SPROC, Connection))
				{
					using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveTables))
					{
						// Set command type and fill dataset
						retrieveTables.CommandType = CommandType.StoredProcedure;
						adapter.Fill(availableTables);

						// Filter out un-wanted tables such as system and information schema tables.
						List&lt;string&gt; temp = new List&lt;string&gt;();
						foreach (DataRow row in availableTables.Tables[0].Select(&quot;TABLE_TYPE='TABLE' and TABLE_OWNER &lt;&gt; 'sys' AND TABLE_OWNER &lt;&gt; 'INFORMATION_SCHEMA'&quot;))
							temp.Add(row[&quot;TABLE_NAME&quot;].ToString());

						// Get valid table names
						retVal = (from x in temp
								  where !x.Contains(&quot;sysdiagrams&quot;)
								  select x).ToList();
					}
				}
			}

			return retVal;
		}

		/// &lt;summary&gt;
		/// Retrieves a list of child tables
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;tableName&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		protected List&lt;string&gt; ChildTables(string parentTableName)
		{
			// Pre-allocate return value
			List&lt;string&gt; retVal = new List&lt;string&gt;();

			// Begin process of fetching database tables
			using (DataSet availableTables = new DataSet(&quot;AvailableTables&quot;))
			{
				using (SqlCommand retrieveTables = new SqlCommand(LibraryConstants.F_KEYS_SPROC, Connection))
				{
					using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveTables))
					{
						// Set command type and fill dataset
						retrieveTables.CommandType = CommandType.StoredProcedure;
						retrieveTables.Parameters.AddWithValue(&quot;@pktable_name&quot;, parentTableName);
						adapter.Fill(availableTables);

						// Filter out un-wanted tables such as system and information schema tables.
						foreach (DataRow row in availableTables.Tables[0].Rows)
						{
							if (row[&quot;fkcolumn_name&quot;].ToString().Contains(parentTableName))
								retVal.Add(row[&quot;fktable_name&quot;].ToString());
						}
					}
				}
			}

			return retVal;
		}

		/// &lt;summary&gt;
		/// Retrieves a list of columns from a database table
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;tableName&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		protected DataTable Columns(string tableName)
		{
			// Pre-allocate return value
			DataTable retVal = new DataTable();

			// Begin process of fetching table columns
			using (DataSet availableColumns = new DataSet(&quot;AvailableColumns&quot;))
			{
				using (SqlCommand retrieveColumns = new SqlCommand(LibraryConstants.COLUMNS_SPROC, Connection))
				{
					using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveColumns))
					{
						// Set command type and fill dataset
						retrieveColumns.CommandType = CommandType.StoredProcedure;
						retrieveColumns.Parameters.AddWithValue(&quot;@table_name&quot;, tableName);
						adapter.Fill(availableColumns);

						// Set return value
						if (availableColumns.Tables.Count &gt; 0)
							retVal = availableColumns.Tables[0];
					}
				}
			}

			return retVal;
		}

		/// &lt;summary&gt;
		/// Returns the promary key status of a given column
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;tableName&quot;&gt;&lt;/param&gt;
		/// &lt;param name=&quot;columnName&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		protected bool IsPrimaryKeyColumnName(string tableName, string columnName)
		{
			// Pre-allocate return value
			bool retVal = false;

			// Begin process of fetching table primary key status
			using (DataSet availableKeys = new DataSet())
			{
				using (SqlCommand retrieveKey = new SqlCommand(LibraryConstants.P_KEYS_SPROC, Connection))
				{
					using (SqlDataAdapter adapter = new SqlDataAdapter(retrieveKey))
					{
						// Set command type and fill dataset
						retrieveKey.CommandType = CommandType.StoredProcedure;
						retrieveKey.Parameters.AddWithValue(&quot;@table_name&quot;, tableName);
						adapter.Fill(availableKeys);

						if (availableKeys.Tables.Count &gt; 0)
						{
							if (availableKeys.Tables[0].Rows.Count &gt; 0)
							{
								foreach (DataRow row in availableKeys.Tables[0].Rows)
								{
									if (availableKeys.Tables[0].Rows[0][&quot;COLUMN_NAME&quot;].ToString().Equals(columnName))
									{
										retVal = true;
										break;
									}
								}
							}
						}
					}
				}
			}

			return retVal;
		}
		#endregion
	}
}
</pre>
<p>
As seen by the code in the TargetSchemaInfo class, all data access methods are fairly similar with the exception that they make use of different system procedure calls. It is noted that due to the similarity of these methods, these methods could be combined and simply passed the LibraryConstans constant that they should use for whatever stored procedure they should be using. For demonstration purposes however, these methods have been split so as to clearly demonstrate each operation as clearly as possible.
</p>
<p>
The last step before we complete the CodeGenerator.Core assembly is to add the one class that will feed XML formatted metadata to the code generator. Prior to creating this class, it seems appropriate, without getting into too much detail, show the XML schema of the generated XML. This will give us an ideal view of how we need to generate our metadata, step by step. The following is an extract of the XML metadata we will be producing:
</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;metadata&gt;
	&lt;project server=&quot;POSEIDON&quot; database=&quot;CodeGeneration&quot; created=&quot;5/28/2009&quot; objectnamespace=&quot;CodeGeneration&quot; sqlcodeobjectprefix=&quot;codegeneration&quot; /&gt;
	&lt;personalization includepersonaldata=&quot;true&quot;&gt;
		&lt;developername&gt;Ramon E. Tristani&lt;/developername&gt;
		&lt;company&gt;PCSWebLabs&lt;/company&gt;
		&lt;position&gt;Software Architect&lt;/position&gt;
		&lt;developerurl&gt;http://www.pcsweblabs.com&lt;/developerurl&gt;
		&lt;copyright&gt;This stuff is copyrighted by the powers of Hello World and foo vars!&lt;/copyright&gt;
	&lt;/personalization&gt;
	&lt;databasetables count=&quot;3&quot;&gt;
		&lt;table name=&quot;Gender&quot; type=&quot;table&quot; haschildren=&quot;true&quot; objectindex=&quot;1&quot;&gt;
			&lt;columns columncount=&quot;6&quot;&gt;
				&lt;column name=&quot;GenderID&quot; datatype=&quot;int identity&quot; length=&quot;10&quot; primarykeystatus=&quot;true&quot; nullable=&quot;true&quot; columnindex=&quot;0&quot; defaultvalue=&quot;nodefault&quot; /&gt;
				&lt;column name=&quot;Type&quot; datatype=&quot;nvarchar&quot; length=&quot;50&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;1&quot; defaultvalue=&quot;nodefault&quot; /&gt;
				&lt;column name=&quot;Created&quot; datatype=&quot;datetime&quot; length=&quot;23&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;2&quot; defaultvalue=&quot;getdate&quot; /&gt;
				&lt;column name=&quot;Updated&quot; datatype=&quot;datetime&quot; length=&quot;23&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;3&quot; defaultvalue=&quot;getdate&quot; /&gt;
				&lt;column name=&quot;IsActive&quot; datatype=&quot;bit&quot; length=&quot;1&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;4&quot; defaultvalue=&quot;1&quot; /&gt;
				&lt;column name=&quot;Description&quot; datatype=&quot;nvarchar&quot; length=&quot;512&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;5&quot; defaultvalue=&quot;nodefault&quot; /&gt;
			&lt;/columns&gt;
			&lt;childtables&gt;
				&lt;childtable name=&quot;Person&quot; type=&quot;table&quot;&gt;
					&lt;columns columncount=&quot;8&quot;&gt;
						&lt;column name=&quot;PersonID&quot; datatype=&quot;int identity&quot; length=&quot;10&quot; primarykeystatus=&quot;true&quot; nullable=&quot;true&quot; columnindex=&quot;0&quot; defaultvalue=&quot;nodefault&quot; /&gt;
						&lt;column name=&quot;GenderID&quot; datatype=&quot;int&quot; length=&quot;10&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;1&quot; defaultvalue=&quot;nodefault&quot; /&gt;
						&lt;column name=&quot;FullName&quot; datatype=&quot;nvarchar&quot; length=&quot;50&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;2&quot; defaultvalue=&quot;nodefault&quot; /&gt;
						&lt;column name=&quot;Age&quot; datatype=&quot;int&quot; length=&quot;10&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;3&quot; defaultvalue=&quot;nodefault&quot; /&gt;
						&lt;column name=&quot;Created&quot; datatype=&quot;datetime&quot; length=&quot;23&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;4&quot; defaultvalue=&quot;getdate&quot; /&gt;
						&lt;column name=&quot;Updated&quot; datatype=&quot;datetime&quot; length=&quot;23&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;5&quot; defaultvalue=&quot;getdate&quot; /&gt;
						&lt;column name=&quot;IsActive&quot; datatype=&quot;bit&quot; length=&quot;1&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;6&quot; defaultvalue=&quot;1&quot; /&gt;
						&lt;column name=&quot;Description&quot; datatype=&quot;nvarchar&quot; length=&quot;512&quot; primarykeystatus=&quot;false&quot; nullable=&quot;true&quot; columnindex=&quot;7&quot; defaultvalue=&quot;nodefault&quot; /&gt;
					&lt;/columns&gt;
				&lt;/childtable&gt;
			&lt;/childtables&gt;
		&lt;/table&gt;
	&lt;/databasetables&gt;
&lt;/metadata&gt;
</pre>
<p>
As you can see, with what we have so far we can get at a lot of information from our generation target without even using a hint of SQLDMO or SMO. We do this by way of the MetadataGenerator class. This class is responsible for creating the entire XML content we will need in future phases of our project. Without further delay, add the MetadataGenerator class to the project and have this new class inherit from our previous class TargetShemaInfo. Add the following code to this class:
</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Xml.Linq;
using System.Collections;

namespace CodeGenerator.Core
{
	/// &lt;summary&gt;
	/// MetadataGenerator class
	/// &lt;/summary&gt;
	public class MetadataGenerator : TargetSchemaInfo
	{
		#region Constructors
		/// &lt;summary&gt;
		/// Default constructor
		/// &lt;/summary&gt;
		public MetadataGenerator() : base() { }
		#endregion

		#region Utility Methods
		/// &lt;summary&gt;
		/// Returns a basic metadata XML document
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;tables&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		private XElement CreateBasicDocument(List&lt;string&gt; tables)
		{
			return new XElement(&quot;metadata&quot;,
							new XElement(&quot;project&quot;,
								new XAttribute(&quot;server&quot;, SqlServerInstance),
								new XAttribute(&quot;database&quot;, TargetDatabase),
								new XAttribute(&quot;created&quot;, DateTime.Now.ToShortDateString()),
								new XAttribute(&quot;objectnamespace&quot;, TargetDatabase),
								new XAttribute(&quot;sqlcodeobjectprefix&quot;, TargetDatabase.ToLower())),
							new XElement(&quot;personalization&quot;,
								new XAttribute(&quot;includepersonaldata&quot;, IncludePersonalization),
								new XElement(&quot;developername&quot;, DeveloperName),
								new XElement(&quot;company&quot;, Company),
								new XElement(&quot;position&quot;, Position),
								new XElement(&quot;developerurl&quot;, DeveloperUrl),
								new XElement(&quot;copyright&quot;, Copyright)),
							new XElement(&quot;databasetables&quot;,
								new XAttribute(&quot;count&quot;, tables.Count.ToString())));
		}

		/// &lt;summary&gt;
		/// Creates a columns XML element
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;tables&quot;&gt;&lt;/param&gt;
		/// &lt;param name=&quot;i&quot;&gt;&lt;/param&gt;
		/// &lt;param name=&quot;tableColumns&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		private XElement CreateColumnsElement(string tableName, DataTable tableColumns)
		{
			XElement columnsElement = new XElement(&quot;columns&quot;,
							   new XAttribute(&quot;columncount&quot;, tableColumns.Rows.Count.ToString()));
			foreach (DataRow row in tableColumns.Rows)
			{
				if (!(row[&quot;TYPE_NAME&quot;].ToString().Equals(&quot;timestamp&quot;)))
				{
					columnsElement.Add(new XElement(&quot;column&quot;,
						new XAttribute(&quot;name&quot;, row[&quot;COLUMN_NAME&quot;].ToString()),
						new XAttribute(&quot;datatype&quot;, row[&quot;TYPE_NAME&quot;].ToString()),
						new XAttribute(&quot;length&quot;, row[&quot;PRECISION&quot;].ToString()),
						new XAttribute(&quot;primarykeystatus&quot;, IsPrimaryKeyColumnName(tableName, row[&quot;COLUMN_NAME&quot;].ToString()) ? &quot;true&quot; : &quot;false&quot;),
						new XAttribute(&quot;nullable&quot;, row[&quot;NULLABLE&quot;].ToString().Equals(0) ? &quot;false&quot; : &quot;true&quot;),
						new XAttribute(&quot;columnindex&quot;, (int.Parse(row[&quot;ORDINAL_POSITION&quot;].ToString()) - 1).ToString()),
						new XAttribute(&quot;defaultvalue&quot;, row[&quot;COLUMN_DEF&quot;].Equals(DBNull.Value) ? &quot;nodefault&quot; :
											row[&quot;COLUMN_DEF&quot;].ToString().Replace(&quot;(&quot;, string.Empty).Replace(&quot;)&quot;, string.Empty).Replace(&quot;'&quot;, string.Empty))));
				}
			}
			return columnsElement;
		}

		/// &lt;summary&gt;
		/// Creates a child tables element
		/// &lt;/summary&gt;
		/// &lt;param name=&quot;childTables&quot;&gt;&lt;/param&gt;
		/// &lt;param name=&quot;columnsElement&quot;&gt;&lt;/param&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		private XElement CreateChildTablesElement(List&lt;string&gt; childTables, ref XElement columnsElement)
		{
			XElement childTablesElement = new XElement(&quot;childtables&quot;);
			if (childTables.Count &gt; 0)
			{
				foreach (string childTable in childTables)
				{
					// Create child table node
					XElement childTableElement = new XElement(&quot;childtable&quot;,
						new XAttribute(&quot;name&quot;, childTable),
						new XAttribute(&quot;type&quot;, &quot;table&quot;));

					// Parse columns
					columnsElement = CreateColumnsElement(childTable, Columns(childTable));

					// Add columns to child table element
					childTableElement.Add(columnsElement);

					// Add child table to child tables element
					childTablesElement.Add(childTableElement);
				}
			}
			return childTablesElement;
		}

		/// &lt;summary&gt;
		/// Returns an XML metadata representation of the target database
		/// &lt;/summary&gt;
		/// &lt;returns&gt;&lt;/returns&gt;
		public string GetMetadataXml()
		{
			// Pre-allocate return value
			string retVal = string.Empty;

			if (Connection.State.Equals(ConnectionState.Open))
			{
				// Fetch tables
				List&lt;string&gt; tables = DatabaseTables();

				// Process tables
				if (tables.Count &gt; 0)
				{
					// Create basic document
					XElement element = CreateBasicDocument(tables);

					// Create document from current XML data
					XDocument doc = new XDocument(element);

					// Reference the &quot;databasetables&quot; node as this node will be heavily modified
					XElement databaseTables = doc.Root.Element(&quot;databasetables&quot;);
					for (int i = 0; i &lt; tables.Count; i++)
					{
						// Retrieve child tables
						List&lt;string&gt; childTables = ChildTables(tables[i]);
						XElement tableElement = new XElement(&quot;table&quot;);
						tableElement.Add(new XAttribute(&quot;name&quot;, tables[i]));
						tableElement.Add(new XAttribute(&quot;type&quot;, &quot;table&quot;));
						tableElement.Add(new XAttribute(&quot;haschildren&quot;, childTables.Count &gt; 0 ? &quot;true&quot; : &quot;false&quot;));
						tableElement.Add(new XAttribute(&quot;objectindex&quot;, i.ToString()));

						#region Load Columns
						// Parse out table columns
						XElement columnsElement = CreateColumnsElement(tables[i], Columns(tables[i]));

						// Add columns to table element
						tableElement.Add(columnsElement);
						#endregion

						// Load child tables
						tableElement.Add(CreateChildTablesElement(childTables, ref columnsElement));

						// Add table element to database tables container node
						databaseTables.Add(tableElement);
					}

					// Set return XML
					retVal = element.ToString();
				}

				// Close connection to the database
				Connection.Close();
			}

			return retVal;
		}
		#endregion
	}
}
</pre>
<p>
The one thing to note with this class is that LINQ to XML is used exclusively for the creation of what will be our XML formatted metadata output. Additionally, having followed a clear inheritance path, we have managed to implement an object with the sole purpose or generating metadata from the generation target.Having worked on similar objects that use the XML DOM objects such as XMLWriter objects, I can attest that our code would have been 4 times as long than it would by using LINQ to XML as we have done so here. At this point, our CodeGenerator.Core assembly is complete for all effective purposes of this tutorial and should look like the following diagram:
</p>
<div id="attachment_44" class="wp-caption alignnone" style="width: 505px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/05/codegenerationcoreclassdiagram.png" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/05/codegenerationcoreclassdiagram.png" alt="Code Generation Core Class Diagram" title="Code Generation Core Class Diagram" width="495" height="907" class="size-full wp-image-44" /></a><p class="wp-caption-text">Code Generation Core Class Diagram</p></div>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">The Code Generator - Testing the Metadata</h2>
<p>
At this point, we are ready to test our assembly output and we will do so by adding a new Console Application project to the Visual Studio solution called CodeGenerator. After creating the project, two things need to happen and those are:
</p>
<ol>
	<li>Add a reference to the CodeGenerator.Core project</li>
	<li>Add the App.config file to the new project</li>
</ol>
<p>
While the structure of the App.config file should be clear from what we have seen in the CoreBase class, the following configuration presents a sample of what this file must look like:
</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;configuration&gt;
	&lt;appSettings&gt;
		&lt;!-- TARGET INFORMATION --&gt;
		&lt;add key=&quot;SqlServerInstance&quot; value=&quot;YOUR_SERVER_INSTANCE&quot; /&gt;
		&lt;add key=&quot;TargetDatabase&quot; value=&quot;CodeGeneration&quot; /&gt;
		
		&lt;!-- PERSONALIZATION --&gt;
		&lt;add key=&quot;IncludePersonalization&quot; value=&quot;true&quot; /&gt;
		&lt;add key=&quot;DeveloperName&quot; value=&quot;YOUR_NAME&quot; /&gt;
		&lt;add key=&quot;Company&quot; value=&quot;YOUR_COMPANY&quot; /&gt;
		&lt;add key=&quot;Position&quot; value=&quot;YOUR_POSITION&quot; /&gt;
		&lt;add key=&quot;DeveloperUrl&quot; value=&quot;YOUR_URL&quot; /&gt;
		&lt;add key=&quot;Copyright&quot; value=&quot;YOUR_COPYRIGHT_INFO&quot; /&gt;
	&lt;/appSettings&gt;
	&lt;connectionStrings&gt;
		&lt;add name=&quot;MasterDatabaseConnectionString&quot; connectionString=&quot;Data Source=YOUR_SERVER_INSTANCE;Initial Catalog=master;Integrated Security=True&quot; providerName=&quot;System.Data.SqlClient&quot; /&gt;
		&lt;add name=&quot;CodeGeneration&quot; connectionString=&quot;Data Source=YOUR_SERVER_INSTANCE;Initial Catalog=CodeGeneration;Integrated Security=True&quot; providerName=&quot;System.Data.SqlClient&quot; /&gt;
	&lt;/connectionStrings&gt;
&lt;/configuration&gt;
</pre>
<p>
The only thing that remains to be done to this configuration is to plug in your own values where the value tokens have been placed. Next, we need to edit the Program class of the CodeGenerator project in order to make use of the CodeGenerator.Core assembly's new metadata extraction capabilities. To do so, add the following code to your Program class:
</p>
<pre class="brush: csharp;">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CodeGenerator.Core;

namespace CodeGenerator
{
	class Program
	{
		static void Main(string[] args)
		{
			//
			MetadataGenerator meta = new MetadataGenerator();
			Console.WriteLine(meta.GetMetadataXml());

			// Hang the console
			Console.Read();
		}
	}
}
</pre>
<p>
Go ahead, build and take the application for a spin! After doing so, if all goes well, you should be able to see a console window, complete with XML metadata output as seen in the following screen capture:
</p>
<div id="attachment_68" class="wp-caption alignnone" style="width: 485px"><a href="http://www.pcsweblabs.com/wp-content/uploads/2009/05/metadataoutput.png" target="_blank"><img src="http://www.pcsweblabs.com/wp-content/uploads/2009/05/metadataoutput.png" alt="Metadata Output" title="Metadata Output" width="475" height="332" class="size-full wp-image-68" /></a><p class="wp-caption-text">Metadata Output</p></div>
<p>
The output basically is a complete regurgitation of metadatadata to the screen. As such, this step concludes this tutorial
</p>
<h2 style="border-bottom: 1px dashed gray; padding-bottom: 2px;">Conclusion</h2>
<p>
In this tutorial we have explored the key concepts of metadata extraction from SQL Server for the purpose of creating the building blocks of a code generation utility. While exploring these concepts, we have gained exposure on how to extract database information from SQL Server using system procedures, how to create XML documents with LINQ to SQL, and how to bring these concepts together. Future articles on code generation will build on the concepts and projects covered in this article all the way to the completion of your very own code generator. 
</p>
<p>
Get the <a href='http://www.pcsweblabs.com/wp-content/uploads/2009/05/codegenerator.zip'>source code</a> for this article.
</p>

        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
        <input type="hidden" name="cmd" value="_xclick" />
    <div style="width: auto; border: 1px solid silver; margin-top: 10px;"><div style="width: auto; padding: 2px; border-bottom: 1px solid silver; background-color: #F7F7F7; font-weight: bold;">Donations</div><div style="padding: 4px;"><input type="hidden" name="business" value="raytristani@gmail.com" /><input type="hidden" name="item_name" value="Donation" /><input type="hidden" name="currency_code" value="USD" /><label style="display: block; margin: 2px;">Show your support to the authors of this site. Your donation is greatly appreciated.</label><input type="image" src="http://www.pcsweblabs.com/wp-content/plugins/wp-simple-paypal-donation/btn_donate_LG.gif" name="submit" alt="Show your support to the authors of this site. Your donation is greatly appreciated." /></div></div></form>]]></content:encoded>
			<wfw:commentRss>http://www.pcsweblabs.com/index.php/2009/05/29/code-generation-extract-database-metadata/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
