<?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>Blog For .NET</title>
	<atom:link href="http://www.blogfor.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.blogfor.net</link>
	<description>welcome to the blogosphere</description>
	<lastBuildDate>Thu, 31 Dec 2009 03:23:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fixing the UpdatePanelAnimationExtender bug when using multiple updatepanels</title>
		<link>http://www.blogfor.net/2009/12/30/fixing-the-updatepanelanimationextender-bug-when-using-multiple-updatepanels/</link>
		<comments>http://www.blogfor.net/2009/12/30/fixing-the-updatepanelanimationextender-bug-when-using-multiple-updatepanels/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 03:23:25 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ajaxcontroltoolkit]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[asp.net ajax]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=230</guid>
		<description><![CDATA[Recently I came across an annoying bug in the AjaxControlToolkit&#8217;s UpdatePanelAnimationExtender control. We had a page with multiple update panels, each with their own UpdatepanelAnimationExtender. When an asynchronous postback occurred, all the &#8220;OnUpdating&#8221; animations fired, but when the asynchronous postback completed, only the updatepanels that were refreshed by the postback ran their &#8220;OnUpdated&#8221; animations&#8221;.
Here&#8217;s my [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I came across an annoying bug in the AjaxControlToolkit&#8217;s UpdatePanelAnimationExtender control. We had a page with multiple update panels, each with their own UpdatepanelAnimationExtender. When an asynchronous postback occurred, all the &#8220;OnUpdating&#8221; animations fired, but when the asynchronous postback completed, only the updatepanels that were refreshed by the postback ran their &#8220;OnUpdated&#8221; animations&#8221;.</p>
<p>Here&#8217;s my example page with two update panels:<br />
<img class="alignnone size-full wp-image-231" style="margin: 5px; border: black 1px solid;" title="Multiple UpdatePanels Each With An UpdatePanelAnimationExtender" src="http://www.blogfor.net/wp-content/uploads/2009/12/UpdatePanelBugPt1Of3.jpg" alt="Multiple UpdatePanels Each With An UpdatePanelAnimationExtender" width="514" height="162" /></p>
<p>During asynchronous postback, both update panels are faded out:<br />
<img class="alignnone size-full wp-image-235" style="margin: 5px; border: black 1px solid;" title="Asynchronous postback executing, all UpdatePanels are faded out" src="http://www.blogfor.net/wp-content/uploads/2009/12/UpdatePanelBugPt2Of3.jpg" alt="Asynchronous postback executing, all UpdatePanels are faded out" width="480" height="149" /></p>
<p>After the asynchronous postback completes, only the update panel refreshed by the postback fades in:<br />
<img class="alignnone size-full wp-image-236" style="margin: 5px; border: black 1px solid;" title="Asynchronous postback is complete and one UpdatePanel is refreshed, the other still running the OnUpdating animation" src="http://www.blogfor.net/wp-content/uploads/2009/12/UpdatePanelBugPt3Of3.jpg" alt="Asynchronous postback is complete and one UpdatePanel is refreshed, the other still running the OnUpdating animation" width="341" height="144" /></p>
<p>When an asynchronous postback is executed, the client doesn&#8217;t know what update panels will be refreshed (this is determined by the server dynamically), so all the UpdatePanelAnimationExtenders play their OnUpdating animations. The extender javascript is as follows:</p>
<pre class="javascript" name="code">_partialUpdateBeginRequest : function(sender, beginRequestEventArgs) {
	/// &lt;summary&gt;
	/// Method that will be called when a partial update (via an UpdatePanel) begins,
	/// if registerPartialUpdateEvents() has been called.
	/// &lt;/summary&gt;
	/// &lt;param name="sender" type="Object"&gt;
	/// Sender
	/// &lt;/param&gt;
	/// &lt;param name="beginRequestEventArgs" type="Sys.WebForms.BeginRequestEventArgs"&gt;
	/// Event arguments
	/// &lt;/param&gt;
	AjaxControlToolkit.Animation.UpdatePanelAnimationBehavior.callBaseMethod(this, '_partialUpdateBeginRequest', [sender, beginRequestEventArgs]);

	if (!this._postBackPending) {
			this._postBackPending = true;
			this._onUpdated.quit();
			this._onUpdating.play();
	}
},</pre>
<p>When the asynchronous postback completes, however, the behavior only selectively plays the OnUpdated animation if it&#8217;s target update panel has been refreshed:</p>
<pre class="javascript" name="code"> _pageLoaded : function(sender, args) {
	/// &lt;summary&gt;
	/// Method that will be called when a partial update (via an UpdatePanel) finishes
	/// &lt;/summary&gt;
	/// &lt;param name="sender" type="Object"&gt;
	/// Sender
	/// &lt;/param&gt;
	/// &lt;param name="args" type="Sys.WebForms.PageLoadedEventArgs"&gt;
	/// Event arguments
	/// &lt;/param&gt;

	if (this._postBackPending) {
			this._postBackPending = false;

			var element = this.get_element();
			var panels = args.get_panelsUpdated();
			for (var i = 0; i &lt; panels.length; i++) {
					if (panels[i].parentNode == element) {
							this._onUpdating.quit();
							this._onUpdated.play();
							break;
					}
			}
	}
},</pre>
<p>The &#8220;fix&#8221; is to stop the OnUpdating animation and play the OnUpdated animation whenever the asynchronous postback completes. We can do this by creating an extender to inherit from UpdatePanelAnimationExtender and &#8220;override&#8221; the _pageLoaded method to:</p>
<pre class="javascript" name="code">	_pageLoaded: function(sender, args) {
		//avoid base call and just cancel animation. this appears to be a design limitation with multiple update panels and multiple instances of update panel animation
		if (this._postBackPending) {
			this._postBackPending = false;
			this._onUpdating.quit();
			this._onUpdated.play();
		}
	}</pre>
<p>A sample reproducing the problem and demonstrating the work around can be found <a href="http://www.blogfor.net/wp-content/uploads/2009/12/UpdatePanelAnimationBug.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2009/12/UpdatePanelAnimationBug.zip');">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/12/30/fixing-the-updatepanelanimationextender-bug-when-using-multiple-updatepanels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UI and Business Validation with Linq to SQL and T4</title>
		<link>http://www.blogfor.net/2009/09/27/ui-and-business-validation-with-linq-to-sql-and-t4/</link>
		<comments>http://www.blogfor.net/2009/09/27/ui-and-business-validation-with-linq-to-sql-and-t4/#comments</comments>
		<pubDate>Sun, 27 Sep 2009 15:44:53 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=201</guid>
		<description><![CDATA[Using T4 and Linq to Sql to generate an extensible rules collection per entity property. The rules collection enables better validation at the UI and business layers.]]></description>
			<content:encoded><![CDATA[<p>Recently I&#8217;ve been working on adding a validation framework to our Linq to Sql based business layer and Asp.Net based UI. While L2Sql provides an &#8220;OnValidate&#8221; partial method to validate changes before they&#8217;re persisted, I needed to catch validation errors much earlier in the stack. My goals were to:</p>
<ol>
<li>Implement the &#8220;OnValidate&#8221; method and throw a custom exception that contains structured information about the invalid properties</li>
<li>Use the information stored in the dbml file to generate boilerplate validation where possible(non-null, max-length, etc.) while allowing developers to add custom validation easily</li>
<li>Integrate with the Asp.Net validation stack to automatically generate validator controls based on rules in the business layers</li>
<li>Expose an IsValid() method to test validation before SubmitChanges is called</li>
</ol>
<p>I&#8217;ve had the fortunate opportunity to work with someone very smart who implemented just such a solution in .net 2.0 using NHibernate and codesmith. While my solution differs in details from his, this is really another implementation of his ideas.</p>
<p>First some class definitions:</p>
<pre name="code" class="c#">
public abstract class RuleBase&lt;T, PropertyType&gt; : IRuleBase
{
	public Type TargetType { get; private set; }
	public String TargetProperty { get; private set; }
	public PropertyInfo PropertyInfo { get; private set; }
	protected abstract String ErrorMessage { get; }
	protected abstract String UIErrorMessage { get; }
	public abstract BaseValidator GetValidator(ClientScriptManager clientScriptManager);

	protected PropertyType GetValue(Object instance)
	{
		return (PropertyType)PropertyInfo.GetValue(instance, null);
	}

	public abstract Boolean IsValid(Object instance, System.Data.Linq.ChangeAction action);

	public RuleBase(String targetProperty)
	{
		if (targetProperty == null)
		{
			throw new ArgumentNullException("targetProperty");
		}
		TargetType = typeof(T);
		TargetProperty = targetProperty;
		PropertyInfo = TargetType.GetProperty(TargetProperty);
		if (PropertyInfo == null)
		{
			throw new ArgumentException(String.Format("Type {0} does not contain a property named {1}", TargetType.FullName, targetProperty), "targetProperty");
		}
	}

	public BrokenRule BrokenRule
	{
		get
		{
			return new BrokenRule(ErrorMessage, UIErrorMessage, TargetType, TargetProperty);
		}
	}
}

public class BrokenRule
{
	public String ErrorMessage { get; private set; }
	public String UIErrorMessage { get; private set; }
	public Type TargetType { get; private set; }
	public String TargetProperty { get; private set; }
}

public class BrokenRulesException : Exception
{
...
	private List&lt;BrokenRule&gt; _brokenRulesInternal;
	private List&lt;BrokenRule&gt; BrokenRulesInternal
	{
		get
		{
			if (_brokenRulesInternal == null)
			{
				_brokenRulesInternal = new List<BrokenRule>();
			}
			return _brokenRulesInternal;
		}
	}

	public IEnumerable&lt;BrokenRule&gt; BrokenRules
	{
		get
		{
			return BrokenRulesInternal;
		}
	}

	public override string ToString()
	{
		var output = new StringBuilder();
		foreach (var brokenRule in BrokenRules)
		{
			output.AppendLine(brokenRule.ErrorMessage);
		}
		output.AppendLine(base.ToString());
		return output.ToString();
	}

}
</pre>
<p>An inheritor of RuleBase validates a property of a type. It must implement a method to validate the property, optionally register a validator for the UI, and exposes messages for the UI and business layers when validation fails.</p>
<p>A BrokenRule encapsulates the information describing a rule that has failed validation. </p>
<p>A BrokenRuleException is an exception that contains a list of BrokenRule objects. Each broken rule describes the type and property it validated and exposes an error message for both the business and UI layers.</p>
<p>Assuming we have a way to retrieve a list of rules for a given type, we can then implement Validate() and the L2Sql partial method OnValidate(ChangeAction action) as:</p>
<pre name="code" class="c#">
public partial class Customer
{
	public IEnumerable&lt;BrokenRule&gt; Validate()
	{
		var action = System.Data.Linq.ChangeAction.None;
		return ValidationRules.Validate&lt;Customer&gt;(this, action);
	}

	partial void OnValidate(System.Data.Linq.ChangeAction action)
	{
		var brokenRules = ValidationRules.Validate&lt;Customer&gt;(this, action);
		if (brokenRules.Count() > 0)
		{
			throw new BrokenRulesException(this.GetType(), brokenRules);
		}
	}
}

public abstract partial class ValidationRules
{
	private static Dictionary&lt;Type, Dictionary&lt;String, List&lt;IRuleBase&gt;&gt;&gt; _rules = new Dictionary&lt;Type, Dictionary&lt;String, List&lt;IRuleBase&gt;&gt;&gt;();

	public static IEnumerable&lt;IRuleBase&gt; GetRules&lt;T&gt;() where T : class
	{
		var ruleLists = new Dictionary&lt;String, List&lt;IRuleBase&gt;&gt;();
		var rules = new List&lt;IRuleBase&gt;();
		var targetInstanceType = typeof(T);
		if (Rules.ContainsKey(targetInstanceType))
		{
			ruleLists = Rules[targetInstanceType];
		}
		else
		{
			return rules;
		}

		foreach (var prop in ruleLists)
		{
			rules.AddRange(prop.Value);
		}
		return rules;
	}

	public static IEnumerable&lt;BrokenRule&gt; Validate&lt;T&gt;(Object instance, System.Data.Linq.ChangeAction action) where T : class
	{
		if (instance == null) {
			throw new ArgumentNullException("instance");
		}
		var brokenRules = GetRules&lt;T&gt;().Where(x => !x.IsValid(instance, action)).Select(x=>x.BrokenRule);
		return brokenRules;
	}
}
</pre>
<p>ValidationRules acts as a singleton object that contains a listing of Rules for each property for each Type validated. When an entity needs to validate itself, a list of rules is built across all the properties in that type and each rule&#8217;s validate method is called.</p>
<p>The actual implementation is a little trickier than this because of the extensive use of static methods and inheritance, but that&#8217;s the general idea.</p>
<p>The next step was to try and generate as many rules as possible &#8211; the easy ones that don&#8217;t involve any business specific logic: maxLenth, required, and date range validation. </p>
<p>The dbml file contains a lot of information about each column&#8217;s type and size. We can tap into this with <a href="http://www.codeplex.com/l2st4" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeplex.com');">l2st4</a> and use a custom T4 template to generate rules for each property. Here&#8217;s the heart of the T4 template:</p>
<pre name="code" class="c#">
<#+
		foreach(Table table in data.Tables)
		{
			foreach(TableClass class1 in table.Classes)
			{
				foreach(var column in class1.Columns)
				{
					if (!column.CanBeNull &#038;&#038; !column.Type.IsPrimitive &#038;&#038; !column.Type.Equals(typeof(Decimal)))
					{
#>
			AddNewRule(new Required<<#= class1.Name#>, <#=column.Type.Name#>>("<#=column.Name#>"));
<#+
					}
					if (typeof(String).Equals(column.Type))
					{
						var maxLength = String.Empty;
						var matches = System.Text.RegularExpressions.Regex.Matches(column.DbType,"(varchar|nchar|char|nvarchar)\\s*\\(\\s*([0-9]+)\\s*\\)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
						if (matches.Count > 0)
						{
							maxLength = matches[0].Groups[2].ToString();
						}
						if (maxLength.Length > 0)
						{
#>
			AddNewRule(new MaxStringLength<<#= class1.Name#>>("<#=column.Name#>", <#=maxLength#>));
<#+
						}//maxLength.Length > 0
					} //column Type is String
					if (typeof(DateTime).Equals(column.Type))
					{
#>
			AddNewRule(new SqlDateTime<<#= class1.Name#>>("<#=column.Name#>"));
<#+
					}
					if (typeof(DateTime?).Equals(column.Type))
					{
#>
			AddNewRule(new SqlDateTimeNullable<<#= class1.Name#>>("<#=column.Name#>"));
<#+
					}
				}
#>
</pre>
<p>For each type, for each column, we generate a rule to ensure that the non-nullable columns are required, that string values are restricted in size and that datetime columns are valid Sql datetimes.</p>
<p>Once we have our dictionary of rules, generating client side validation is relatively straightforward, if not a little limited:</p>
<pre name="code" class="c#">
public class CodeGenFieldValidator : System.Web.UI.WebControls.WebControl
{

	protected override void CreateChildControls()
	{
		this.Controls.Clear();
		if (_type != null &#038;&#038; this.PropertyName.Length > 0 &#038;&#038; this.ControlToValidate.Length > 0)
		{
			var property = _type.GetProperty(this.PropertyName);
			if (property == null)
			{
				throw new InvalidOperationException(String.Format("Cannot find property '{0}' to validate in type '{1}'", PropertyName, _type.FullName));
			}
			var rules = _type.GetMethod("GetRules").Invoke(null, new object[] { PropertyName }) as IEnumerable<IRuleBase>;
			if (rules.Count() > 0)
			{
				foreach (var rule in rules)
				{
					System.Web.UI.WebControls.BaseValidator validationControl = rule.GetValidator(this.Page.ClientScript);
					if (validationControl != null)
					{
						var spanContainingValidator = new Label { CssClass = ValidationItemCssClass };
						validationControl.ControlToValidate = this.ControlToValidate;
						validationControl.Display = this.Display;
						validationControl.ErrorMessage = rule.BrokenRule.UIErrorMessage;
						validationControl.EnableClientScript = this.EnableClientScript;
						validationControl.Enabled = this.Enabled;
						validationControl.SetFocusOnError = this.SetFocusOnError;
						validationControl.ForeColor = this.ForeColor;
						if (!String.IsNullOrEmpty(ValidationGroup))
						{
							validationControl.ValidationGroup = ValidationGroup;
						}
						validationControl.EnableClientScript = true;
						spanContainingValidator.Controls.Add(validationControl);
						//this.Controls.Add(spanContainingValidator);
						this.Controls.Add(validationControl);
					}
				}
			}
		}
		else
		{
			base.ClearChildViewState();
		}
	}

	private Type _type;
	/// <summary>
	/// Gets or sets the name of the class that the control validates against.
	/// Return Value: A partially or fully qualified class name that identifies the type of the object that the type to validate against represents.
	/// The default is an empty string ("").
	/// </summary>
	[DefaultValue("")]
	public string TypeName
	{
		get
		{
			object typeName = this.ViewState["TypeName"];
			if (typeName != null)
			{
				return (string)typeName;
			}
			return string.Empty;
		}
		set
		{
			this.ViewState["TypeName"] = value;
			if (!String.IsNullOrEmpty(value))
			{
				_type = Type.GetType(value, false, true);
				if (_type == null)
				{
					throw new InvalidOperationException("Cannot set TypeName to Type it cannot find");
				}
			}
			else
			{
				_type = null;
			}
		}
	}

	/// <summary>
	/// Gets or sets the name of the property in type to validate against.
	/// The default is an empty string ("").
	/// </summary>
	[DefaultValue("")]
	public string PropertyName
	{
		get
		{
			object propertyName = this.ViewState["PropertyName"];
			if (propertyName != null)
			{
				return (string)propertyName;
			}
			return string.Empty;
		}
		set
		{
			this.ViewState["PropertyName"] = value;
		}
	}

	public CodeGenFieldValidator()
	{
		this.ForeColor = Color.Red;
	}

	/// <summary>
	/// Gets or sets the input control to validate.
	/// Return Value: The input control to validate. The default value is Empty, which indicates that this property is not set.
	/// </summary>
	[TypeConverter(typeof(ValidatedControlConverter)), Themeable(false), DefaultValue(""), IDReferenceProperty]
	public string ControlToValidate
	{
		get
		{
			object controlToValidate = this.ViewState["ControlToValidate"];
			if (controlToValidate != null)
			{
				return (string)controlToValidate;
			}
			return string.Empty;
		}
		set
		{
			this.ViewState["ControlToValidate"] = value;
		}
	}
...
</pre>
<p>and used like so:</p>
<pre name="code" class="xml">
&lt;asp:TextBox ID="tbCompanyName" runat="server" Text='&lt;%# Bind("CompanyName") %&gt;'&gt;
&lt;/asp:TextBox&gt;
&lt;cc:CodeGenFieldValidator
TypeName="LinqToSqlCodeGenValidationSample.Customer, LinqToSqlCodeGenValidationSample"
PropertyName="CompanyName"
ControlToValidate="tbCompanyName"
runat="server"
ID="fvCompanyName"
Display="Dynamic"
ValidationItemCssClass="ValidationItem"
CssClass="ValidationGroup"&gt;&lt;/cc:CodeGenFieldValidator&gt;
</pre>
<p>There&#8217;s a lot more logic built into the generation of the ValidationRules object and the specific rules themselves than I&#8217;ve shown here.<br />
You can find a sample with of all this using the northwind database and a variety of additional validators (numeric, email, mixed case, etc.) <a href="http://www.blogfor.net/wp-content/uploads/2009/09/linqtosqlcodegenvalidationsample.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2009/09/linqtosqlcodegenvalidationsample.zip');">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/09/27/ui-and-business-validation-with-linq-to-sql-and-t4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Generating Business Layer Code T4 against a Linq to Sql DAL</title>
		<link>http://www.blogfor.net/2009/09/03/generating-business-layer-code-t4-against-a-linq-to-sql-dal/</link>
		<comments>http://www.blogfor.net/2009/09/03/generating-business-layer-code-t4-against-a-linq-to-sql-dal/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 02:24:26 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=151</guid>
		<description><![CDATA[T4 template to generate business layer methods against a linq to sql dbml file. Methods include insert/update interceptors, filter objects, and static methods for loading objects by foreign key and by filter.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently gotten into using Microsoft&#8217;s <span style="color: #000000;">Text Template Transformation Toolkit (T4) to automate create the boilerplate code in our business layer. Because the T4 framework comes with Visual Studion 2008 I didn&#8217;t have to purchase and deploy any additional tools to each developer&#8217;s machine. Altough T4 is not the easiest thing to understand, the time savings has proven to be exceptional. Once the initial solution was in place, bringing other developers onboard to use and extend the framework has gone very well.</span></p>
<p>At first I scoured Google for other people&#8217;s T4 templates. I hoped to find a plethora sample templates that would save me the trouble of starting from scratch. What I found instead was a handful of tools to replace the code generated by visual studio when saving a dbml. My goal was not to replace this code, but to extend it &#8211; to make binding asp.net repeaters and gridviews to filtered and sorted listings of records as flexible and easy as possible.</p>
<p>One exceptional tool I came acroos was the <a href="http://www.codeplex.com/t4toolbox" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeplex.com');">T4Toolbox </a>. While the T4Toolbox provides a version of the aforementioned DataContext and entity code generator based on a dbml file, it also provides an exceptional framework for building very extensive T4 templates. Ultimately I chose not to use the T4Toolbox because it required installation and was much more tool than what I needed.</p>
<p>I then stumbled upon the <a href="http://www.codeplex.com/l2st4" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeplex.com');">LINQ to SQL templates for T4 framework</a> (l2st4) project on codeplex.  It also generates a richer data context and entities than the out of the box microsoft. While this wasn&#8217;t what I was looking for, the project does a great job of encapsulating the deserializated dbml file. Using it&#8217;s &#8221;Data&#8221; object we can iterate over all the tables, views, user defined functions, and sprocs in the dbml file and get at their underlying type definitions, relationships, and metadata in a very sensible way.</p>
<p>Using this information, I wrote a T4 template to try and encapsulate most of the boilerplate functionality we need from our data access layer.</p>
<p>My focus was to:</p>
<ul>
<li>set createdby/on and modifiedby/on automatically when inserting/updating records with those fields</li>
<li>create static methods to load records by foreign keys e.g.<br />
public static IQueryable&lt;Order&gt; LoadByCustomer(string customerID, NorthwindDataContext dataContext)</li>
<li>create objects to encapsulate sort, filter, and paging information specific to the entity. Allow developers to extend these objects for custom filtering and sorting.</li>
</ul>
<p>Our applications filter and sort sets of records intensively but are light on creating, updating and deleting records. The use case I followed was to simplify the work needed to bind a gridview/oject data source to the business layer. Given a UI like:</p>
<p><a rel="attachment wp-att-157" href="http://www.blogfor.net/2009/09/03/generating-business-layer-code-t4-against-a-linq-to-sql-dal/gridview/" ><img class="alignnone size-full wp-image-157" title="gridview" src="http://www.blogfor.net/wp-content/uploads/2009/09/gridview.jpg" alt="gridview" width="469" height="158" /></a></p>
<p>The filter at the top allows user&#8217;s to restrict the records by Company name (contains, starts with, ends with, exact match) and by number of orders (&lt;5, &lt;10, etc.). They can also sort on the company name field and the number of orders per customer.</p>
<p>Within the codebehind of the page/user control in the object datasource selecting event:</p>
<pre name="code" class="c#">//user typed code
protected void ods_Selecting(object sender, ObjectDataSourceSelectingEventArgs e)
{
e.InputParameters[0] = BuildFilter();
e.InputParameters[1] = DataContext;
}

//Note: Customer.Filter is a code generated partial class
private Customer.Filter BuildFilter()
{
//Filter to pass to business layer
var filter = new Customer.Filter();
//Filter Company Name by value of textbox
filter.CompanyName.Value = txtContains.Text.Trim();
//Filter on Company Name by dropdown value - Like, Exact Match, Start With, Ends With
filter.CompanyName.MatchType =
(LinqToSqlCodeGenSample.CodeGen.StringFilter.Match)System.Enum.Parse(
typeof(LinqToSqlCodeGenSample.CodeGen.StringFilter.Match),
 ddlMatchType.SelectedValue);
if (ddlNumberOfOrders.SelectedIndex &gt; 0)
{
Int32 maxOrderCount = Int32.Parse(ddlNumberOfOrders.SelectedValue);
//Set Lamdba expression to filter out customers by the number of orders
filter.FilterExpression = x =&gt; x.Orders.Count() &lt; maxOrderCount;
}
return filter;
}

//Stubbed out business layer api (generated by T4 Template)
public static IQueryable&lt;Customer&gt; Load(Filter filter, NorthwindDataContext dataContext)

public static Int32 LoadCount(Filter filter, NorthwindDataContext dataContext)</pre>
<p>The T4 template and a sample solution can be found <a href="http://www.blogfor.net/wp-content/uploads/2009/09/linqtosqlcodegensample.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2009/09/linqtosqlcodegensample.zip');">here</a>.</p>
<p>The &#8220;filter&#8221; objects contain information for sorting, paging, and filtering records. String properties can be filtered by exact match, like, starts with, and ends with.</p>
<p>When a custom sort or filter is necessary, developers can override the filter&#8217;s ProcessCustomSortExpression(String sortExpression) method to add their own custom lamda expression to the Filter object&#8217;s SortCriteria list.</p>
<p>When filtering records by something more than column name, developer can override the ProcessAdditionalFilterInformation(IQueryable&lt;T&gt; qry, U dataContext) method in a filter&#8217;s partial class.</p>
<p>This is by no means a complete solution. Every day we&#8217;ve been finding better ways to implement such a framework. I hope this serves as an example of how to use the l2st4 templates to generate code against a dbml file and gives an idea of how useful it can be.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/09/03/generating-business-layer-code-t4-against-a-linq-to-sql-dal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dynamic Sorting and Filtering with Linq To SQL</title>
		<link>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/</link>
		<comments>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 02:23:18 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[linq to sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=140</guid>
		<description><![CDATA[Dynamic sorting in Linq to Sql using lambda expressions and column names]]></description>
			<content:encoded><![CDATA[<p>A common paradigm in my current work involves separating sort logic from the data access layer that applies it. The end user may sort a table/view by any number of criteria and in fairly complex ways.</p>
<p>One simple way to achieve this is through a switch statement:</p>
<pre name="code" class="c#">private IOrderedQueryable&lt;Customer&gt; SortData(String sortExpression, IQueryable&lt;Customer&gt; query)
  {
   sortExpression = sortExpression ?? "CompanyName";
   IOrderedQueryable&lt;Customer&gt; orderedQuery = null;
   switch (sortExpression)
   {
    case "CompanyName":
     orderedQuery = query.OrderBy(x =&gt; x.CompanyName);
     break;
    case "Count":
     orderedQuery = query.OrderBy(x =&gt; x.Orders.Count());
     break;
    default:
     orderedQuery = query.OrderBy(x =&gt; x);
     break;
   }
   return orderedQuery;
  }</pre>
<p>This quickly breaks down because we would need to include a case for every possible sort expression. There&#8217;s a fairly common approach at <a href="http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">http://weblogs.asp.net/davidfowler/archive/2008/12/11/dynamic-sorting-with-linq.aspx</a> to dynamically sort on a table&#8217;s columns. This works well but the approach does not lend itself to more complicated expressions e.g. sort customers by their number of orders.</p>
<p>We sought to create a framework for developers to filter and sort listings by any combination of criteria. As long as Linq to Sql supported the lamda expression, the developer should be free to populate a custom &#8220;filter&#8221; object with a list of &#8220;where&#8221; and &#8220;order by&#8221; information needed to act upon the table or view.</p>
<p>When filtering a sequence, Linq to Sql has no trouble converting lamda expressions that return booleans into t-sql &#8220;where&#8221; clauses &#8211; the boolean return value matches the necessary return value of the sql expression generated. The filter expression then can simply be:</p>
<pre name="code" class="c#">
Expression&lt;Func&lt;T, Boolean&gt;&gt; filterExpression
</pre>
<p>When sorting a sequence, however, the lamdba expression must return a Type that supports IComparable. A simplistic approach to dynamic sorting would then be to use sort expressions of the form:</p>
<pre name="code" class="c#">Expression&lt;Func&lt;T, IComparable&gt;&gt; sortExpression</pre>
<p>and apply them as</p>
<pre name="code" class="c#">sortedQry = qry.OrderBy(sortExpression);</pre>
<p>This will work just fine when querying objects, but will fail when used with Linq to Sql. Depending on the return type, the runtime may force a cast to IComparable &#8211; something Linq to Sql doesn&#8217;t know how to do.</p>
<p><a rel="attachment wp-att-141" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/icompareableerror/" ><img class="alignnone size-medium wp-image-141" title="icompareableerror" src="http://www.blogfor.net/wp-content/uploads/2009/09/icompareableerror.png" alt="icompareableerror" width="601" height="263" /></a></p>
<p>The error specifically ocurrs when the return value of the expression is a DateTime, Int32, etc. </p>
<p>To work around this we need to avoid casting the return value of the lamdba expression and instead let Linq to Sql know explicitly what type the expression returns.</p>
<p><a rel="attachment wp-att-143" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/templatedlamdbal2sqltooltip-noicompare/" ><img class="alignnone size-full wp-image-143" title="templatedlamdbal2sqltooltip-noicompare" src="http://www.blogfor.net/wp-content/uploads/2009/09/templatedlamdbal2sqltooltip-noicompare.jpg" alt="templatedlamdbal2sqltooltip-noicompare" width="515" height="37" /></a></p>
<p>instead of this:</p>
<p><a rel="attachment wp-att-144" href="http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/icompareablel2sqltooltip-icomparablecast/" ><img class="alignnone size-full wp-image-144" title="icompareablel2sqltooltip-icomparablecast" src="http://www.blogfor.net/wp-content/uploads/2009/09/icompareablel2sqltooltip-icomparablecast.jpg" alt="icompareablel2sqltooltip-icomparablecast" width="570" height="40" /></a></p>
<p>We could, for instance, create a variable for each return type:</p>
<pre name="code" class="c#">
Expression&lt;Func&lt;T, DateTime&gt;&gt; sortExpressionDate

Expression&lt;Func&lt;T, Int32&gt;&gt; sortExpressionInt32

...</pre>
<p>Such a framework is too cumbersome to use effectively. Instead, we can avoid the cast by telling .net at compile time the return type of the lamda expression.</p>
<pre name="code" class="c#">Expression&lt;Func&lt;T, TKey&gt;&gt; SortExpression</pre>
<p> for example:</p>
<pre name="code" class="c#">Expression&lt;Func&lt;Customer, Int32&gt;&gt; sortExpression = x =&gt; x.Orders.Count();</pre>
<p>In my specific case, I used a filter to encapsulate the logic needed to filter and sort a sequence.</p>
<pre name="code" class="c#">public class Filter&lt;T&gt;
 {
  /// &lt;summary&gt;
  /// the list of filters applied to the sequence. The filters will act as a series of "and" clauses against the data source.
  /// &lt;/summary&gt;
  public List&lt;Expression&lt;Func&lt;T, Boolean&gt;&gt;&gt; Filters...

   /// &lt;summary&gt;
  /// the list of sorts to apply to the resulting sequence of items.
  /// &lt;/summary&gt;
  public List&lt;ISortOrder&lt;T&gt;&gt; SortCriteria...
  }

public interface ISortOrder&lt;T&gt;
 {
  SortDirection Direction { get; set; }
  IOrderedQueryable&lt;T&gt; ApplyOrdering(IQueryable&lt;T&gt; query, Boolean useThenBy);
 }</pre>
<p>For example, the following code filters by companyName and a minimum number of orders; then sorts by the column name specified by the &#8220;propertyNameToSortBy&#8221; variable followed by the count of orders:</p>
<pre name="code" class="c#">var filter = new Filter&lt;Customer&gt;();

filter.Filters.Add(x =&gt; x.CompanyName.Contains(searchText));

filter.Filters.Add(x =&gt; x.Orders.Count &lt; numberOfOrders);

filter.SortCriteria.Add(new FieldSortOrder&lt;Customer&gt;(propertyNameToSortBy));

var sortBy = new ExpressionSortOrder&lt;Customer, Int32&gt;()
     {
      SortExpression = x =&gt; x.Orders.Count,
      Direction = (sortExpression.ToLowerInvariant().EndsWith("desc")) ? DynamicSorter.SortDirection.Descending : DynamicSorter.SortDirection.Ascending
     };
     filter.SortCriteria.Add(sortBy);

return FilterItems(filter);</pre>
<p> the code for the FilterItems method then is relatively simple:</p>
<pre name="code" class="c#">public static IEnumerable&lt;Customer&gt; FilterItems(Filter&lt;Customer&gt; filter)
  {
   var dc = new NorthwindDataContext();

   IQueryable&lt;Customer&gt; sequence = dc.Customers;
   foreach (var filterClause in filter.Filters)
   {
    sequence = sequence.Where(filterClause);
   }
   if (filter.SortCriteria.Count &gt; 0)
   {
    var sortCriteria = filter.SortCriteria[0];
    var orderedSequence = sortCriteria.ApplyOrdering(sequence, false);
    if (filter.SortCriteria.Count &gt; 1)
    {
     for (var i = 1; i &lt; filter.SortCriteria.Count; i++)
     {
      sortCriteria = filter.SortCriteria[i];
      orderedSequence = sortCriteria.ApplyOrdering(sequence, false);
     }
    }
    sequence = orderedSequence;
   }
   return sequence;
  }</pre>
<p>In the end, we used T4 templates to codegen entity specific filter objects and static methods to filter tables and views &#8211; more about that in my next post.</p>
<p>A sample northwind based sample can be found <a href="http://www.blogfor.net/wp-content/uploads/2009/09/dynamicsorter.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2009/09/dynamicsorter.zip');">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/09/03/dynamic-sorting-and-filtering-with-linq-to-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gridview + Object Data Source &#8211; fun with custom pagers</title>
		<link>http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/</link>
		<comments>http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/#comments</comments>
		<pubDate>Fri, 04 Sep 2009 02:19:19 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=120</guid>
		<description><![CDATA[custom gridview to leverage functionality of the object data source to provide a better paging experience and easier coding of custom pager templates.]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a lot of functionality bundled into the asp.net gridview. Some developers I know, however, have avoided using it. They&#8217;ve had bad experiences with datagrids (the precursor to the gridview), custom pagers, and seem to have a general misunderstanding of the control. Like so many other asp.net controls &#8211; it&#8217;s perfect for demos but can be exceptionally difficult to customize. So instead we&#8217;ve custom coded the same functionality using repeaters and custom controls.</p>
<p>Fortunately for me, I have a good friend who took the time to truly understand the gridview and bend it to his will. The final product was scalable, flexible, extensible, and most importantly highly reusable. </p>
<p>At my current job, we&#8217;ve spent a lot of time reinventing the gridview wheel &#8211; creating customized &#8220;listings&#8221; that allowed for some combination of sorting, paging, changing of page size. Because each client&#8217;s design required slight variations in functionality and appearance we had to code each one separately. For example one client&#8217;s requirements called for a pager that with links like &#8220;1 <strong>2</strong> 3&#8230; 100 Next&#8221; where &#8221;Next&#8221; takes you to page 3. Another client required </em> &#8220;1 <strong>2</strong> 3 Next&#8221; where &#8220;Next&#8221; counterintuitively navigates you to page 4.</p>
<p>There were several pieces to this puzzle that had little to do with gridviews. Internally, we worked with the design team to standardize the listings they put into designs and proposals. As much as possible and we implemented a standard data access paradigm across our codebase. Most difficult of all, we worked with each team member to embrace and improve the framework as a whole to meet their individual needs. It&#8217;s not perfect and adoption will take time, but we&#8217;ve made great strides moving away from project managers afraid to ask &#8220;How much time will it take to allow users to sort that listing?&#8221; and &#8220;How much will it cost us to add paging?&#8221; .</p>
<p>When I began write a framework control to use on our new projects I didn&#8217;t want to use the out of the box gridview pager:<br />
<a rel="attachment wp-att-121" href="http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/basegridview/" ><img class="alignnone size-full wp-image-121" title="basegridview" src="http://www.blogfor.net/wp-content/uploads/2009/09/basegridview.jpg" alt="basegridview" width="622" height="90" /></a></p>
<p>Instead, most of our clients requirements have some variation on this:<br />
<a rel="attachment wp-att-122" href="http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/custompager/" ><img class="alignnone size-full wp-image-122" title="custompager" src="http://www.blogfor.net/wp-content/uploads/2009/09/custompager.jpg" alt="custompager" width="685" height="96" /></a></p>
<p>There were a lot of solutions online to do custom pagers that involving repeaters and other custom controls. Much of our own attempts involved complicated viewstate managers to track page index, page size, and sort expressions.<br />
Many of the gridview based examples didn&#8217;t leverage the object data source and acted instead upon the IEnumerable bound to the gridview&#8217;s datasource. This prevented the pager from readily showing the total number of records and pages.</p>
<p>In my particular case, it wasn&#8217;t a stretch to require an object data source because it&#8217;s the <a href="http://msdn.microsoft.com/en-us/library/5aw1xfh3.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">only data source that the gridview can use to find total count</a>, and our business layer lent itself well to selecting and counting records based on the same criteria.</p>
<p>The default gridview functionality gives custom pager implementers little information to go on. When another developer goes to create a custom pager templates, the gridview doesn&#8217;t give an easy way to get at the necessary information to render a pager- the total number of records, page index, total page count, etc. It also doesn&#8217;t control pager visibility as one would hope, leaving that too up tothe implementer.</p>
<p>To work around this, implementers can now attach to the &#8220;InitializeCustomPager&#8221; event. The eventArgs parameter contains the same information that gridview inheritors get in the &#8220;InitializePager&#8221; override &#8211; specifically, the PagedDataSource object and it&#8217;s properties: CurrentPageIndex, PageCount, PageSize, VirtualCount, etc.</p>
<pre name="code" class="c#">/// &lt;summary&gt;
  /// Set to true to make gridview render with its default pager
  /// &lt;/summary&gt;
  public Boolean UseDefaultPager { get; set; }

  protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
  {
   base.InitializePager(row, columnSpan, pagedDataSource);
   if (!UseDefaultPager)
   {
    InitializeCustomPagerEventArgs e = new InitializeCustomPagerEventArgs(row, columnSpan, pagedDataSource);
    RaiseInitializeCustomPager(e);
   }
  }

public void RaiseInitializeCustomPager(InitializeCustomPagerEventArgs e)
  {
   if (InitializeCustomPager != null)
   {
    InitializeCustomPager(this, e);
   }
  }

public event InitializeCustomPagerHandler InitializeCustomPager;
public delegate void InitializeCustomPagerHandler(object sender, InitializeCustomPagerEventArgs e);
  public class InitializeCustomPagerEventArgs
  {
   public GridViewRow PagerRow { get; private set; }
   public int ColumnSpan { get; private set; }
   public PagedDataSource PagedDataSource { get; private set; }
   internal InitializeCustomPagerEventArgs(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
   {
    this.ColumnSpan = columnSpan;
    this.PagedDataSource = pagedDataSource;
    this.PagerRow = row;
   }
  }</pre>
<p>To illustrate this, check out the &#8220;AlternatePager.aspx&#8221; page of the sample code at the end of this post.</p>
<p>The more paging we did, the more we began using a default sort when the control was first rendered. I must confess, my good friend Mr. Boudreau aka the &#8220;Gridview pimp&#8221; came up with the solution:</p>
<pre name="code" class="c#">public String DefaultSortExpression
  {
   get
   {
    if (ViewState["defaultSortExpression"] == null)
    {
     ViewState["defaultSortExpression"] = String.Empty;
    }
    return (String)ViewState["defaultSortExpression"];
   }
   set
   {
    ViewState["defaultSortExpression"] = value;
   }
  }
 public SortDirection DefaultSortDirection
  {
   get
   {
    if (ViewState["defaultSortDirection"] == null)
    {
     ViewState["defaultSortDirection"] = SortDirection.Ascending;
    }
    return (SortDirection)ViewState["defaultSortDirection"];
   }
   set
   {
    ViewState["defaultSortDirection"] = value;
   }
  }
protected override void OnInit(EventArgs e)
  {
   base.OnInit(e);
   if (!String.IsNullOrEmpty(DefaultSortExpression))
   {
    Sort(DefaultSortExpression, DefaultSortDirection);
   }
  }
protected override DataSourceSelectArguments CreateDataSourceSelectArguments()
  {
   var arguments = base.CreateDataSourceSelectArguments();
   //Sets up our default sort expression and direction on the gridview.
   if (String.IsNullOrEmpty(arguments.SortExpression) &amp;&amp; (!String.IsNullOrEmpty(DefaultSortExpression)))
   {
    arguments.SortExpression = DefaultSortExpression;
    if (!arguments.SortExpression.EndsWith("DESC") &amp;&amp; !arguments.SortExpression.EndsWith("ASC"))
    {
     if (DefaultSortDirection == SortDirection.Descending)
     {
      arguments.SortExpression += " DESC";
     }
     else
     {
      arguments.SortExpression += " ASC";
     }
    }
   }
   return arguments;
  }</pre>
<p>Each pager section &#8211; page size, page links, and row count - is contained within a container div. Each of these divs is styled according to the properties DefaultPagerRowCountCssClass, DefaultPagerPageLinkCssClass, and DefaultPagerPageSizeCssClass.</p>
<p>Lastly, the ability to change data pages within the gridview already has a large amount of support built into the control. Simply give the page navigatoin controls inside your pager a CommandName of &#8220;Page&#8221; and a CommandArgument of pageIndex(1,2,3,etc.), &#8220;Next&#8221;, &#8220;Previous&#8221;, &#8220;First&#8221; or &#8220;Last&#8221;.</p>
<p>My work can be found <a rel="attachment wp-att-123" href="http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/customgridview/" >here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/09/03/gridview-object-data-source-fun-with-custom-pagers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More thoughts on interviews</title>
		<link>http://www.blogfor.net/2009/05/04/more-thoughts-on-interviews/</link>
		<comments>http://www.blogfor.net/2009/05/04/more-thoughts-on-interviews/#comments</comments>
		<pubDate>Tue, 05 May 2009 02:09:38 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[general]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=110</guid>
		<description><![CDATA[My coworkers and I have begun the painful process of hiring again. After conducting too many interviews to count I have a few observations to make.
First and foremost the goal of the interview is to determine if the candidate is a good fit for the position. It&#8217;s also important, however, to use the interview to [...]]]></description>
			<content:encoded><![CDATA[<p>My coworkers and I have begun the painful process of hiring again. After conducting too many interviews to count I have a few observations to make.</p>
<p>First and foremost the goal of the interview is to determine if the candidate is a good fit for the position. It&#8217;s also important, however, to use the interview to inform the candidate about the company, the position, and the department. There&#8217;s little point in finding a great candidate if you haven&#8217;t sold the candidate on the position and the team. To do all this consistently with a variety of candidates is difficult and takes practice.</p>
<p>Many interviewers conduct litmus tests more than interviews &#8211; they believe there are certain concepts that good developers innately understand. &#8220;What is a pointer?&#8221;, &#8220;How do you model a many-to-many relationship in the database?&#8221;, &#8220;How do you reverse a singly linked list?&#8221;</p>
<p>Skeptics deride these questions as mere trivia. They say that anyone can look algorithms and definitions up in books. The problem with such tests is that they set a bar for &#8220;good enough&#8221; but provide no way to measure between &#8220;good&#8221; and &#8220;great&#8221;. An effective interviewer increases the chances of making good hire by balancing the position requirements against the candidate&#8217;s skills, personality, and logistics (salary, title, benefits). Such tests don&#8217;t provide enough detail.</p>
<p>Another common problem with interviewing is the basic approach toward the the position. Some want to find candidates who are merely &#8220;good enough to be here&#8221;. This is a natural by-product of a litmus test interview. Such people honestly believe that interviewing cannot predict with enough accuracy a candidate&#8217;s chance of success. They prefer the mantra &#8220;Easy to hire, easy to fire&#8221;. A similar approach is to compare the candidates against each other and pick the best one. While a candidate may stand out when compared to other candidates, this provides little information about his fit for the position or the team. </p>
<p>Before every interview I conduct, I review the candidate&#8217;s resume in advance. I highlight interview questions that apply to the technologies and experience stated in their resume. I remind myself what my friend told me before my first interview &#8211; that the interview process is as much selling the company, position, and team to the candidate as it is about gathering information from the candidate.</p>
<p>Some interviews go well, others do not. Sometimes we just don&#8217;t connect very well. Sometimes the problems are more systematic &#8211; my questions are too technical and oriented to microsoft technologies than the candidate is comfortable with. It&#8217;s important to try and evaluate the efficacy of the interview independently of one&#8217;s feelings about the candidate. Day to day most of the candidate&#8217;s work will have nothing to do with most of the people he meets during the interview. If we only hired people we related to, we&#8217;d never hire across gender or culture lines.</p>
<p>When I changed jobs a while back I lost access to my original list of interview questions. More importantly, I left the interview team that had proved so successful. My former colleagues are far better interviewers than I and I wanted a place to transcribe some of what we developed for future use. The following is what I&#8217;ve been able to piece together. In some places I have merely paraphrased their questions poorly. When possible I&#8217;ve included their original unblemished questions (with many thanks to Jed and Andrew) and I apologize in advance for the places where I&#8217;ve misquoted them.</p>
<p><em>Phone Screen:</em></p>
<p>Agenda:</p>
<ul>
<li>Introduction</li>
<li>Present interview format</li>
<li>Company overview – size, location, culture, business niche</li>
<li>Position overview – skills, responsibilities, first project</li>
<li>Basic job questions</li>
<li>Technical questions (litmus)</li>
<li>Round out questions (if the interview looks promising)</li>
<li>Next steps</li>
<li>Decision timeline</li>
<li>Thank you</li>
</ul>
<p>Questions:</p>
<ul>
<li>Are you familiar with our company?</li>
<li>Describe your background and a bit about yourself.</li>
<li>Why are you looking for a job?</li>
<li>What kind of position are you looking for?</li>
<li>How much are you currently making?</li>
<li>When can you start?</li>
<li>What are the last several books you&#8217;ve read?</li>
<li>What blogs do you follow?</li>
</ul>
<p>Technical Questions:</p>
<ul>
<li>What is the difference between a class and an object?</li>
<li>What is the difference between a primary key and an index?</li>
<li>What is a singleton object? Can you give an example of one in the .net framework?</li>
<li>What is a static method? Can you give an example of one in the .net framework?</li>
<li>Put the following asp.net control events in order: Page_Load, PreRender, Button_OnClick.</li>
</ul>
<p>Evaluation:</p>
<ul>
<li>Can you understand this person when they describe their work? What about when they describe technical details?</li>
<li>Are the answers to technical questions precise?</li>
<li>Does the candidate show an interest in learning and applying new skills?</li>
</ul>
<p><em>Computer Algorithms and Concepts Interview:</em></p>
<p>Questions:</p>
<ul>
<li>What are some common programming patterns? What examples of patterns can you find in existing frameworks &#8211; .net, asp.net, jQuery, scriptaculous, Elmah, log4net, linq, etc</li>
<li>Pseudo-code the algorithm to reverse a doubly link list.</li>
<li>Pseudo-code an implementation for a stack using primitives.</li>
<li>Psuedo-code an implementation for removing &#8220;z&#8221; characters in a C style string.</li>
<li>What languages do you enjoy programming in? Why?</li>
<li>Imagine an asp.net webform with a single textbox and a single link-button. The user types in a value into the textbox and clicks the link-button.A postback is performed and the page reloads with the textbox already populated. – How does the textbox retain it’s value across the postback? Please be as specific as possible, describing all interactions between systems and communication protocols.</li>
<li>Suppose you have two user controls. One containing a databound list and another containing a link button. How would you rebind the list in the first control in the click event of the link button?</li>
</ul>
<p>Analysis:</p>
<ul>
<li>Can the candidate communicate ideas and concepts well?</li>
<li>Do they understand basic patterns and apply them?</li>
<li>Do they understand basic algorithms and apply them?</li>
<li>Can they site programming principles (SRP, OCP, etc.)?</li>
<li>Are they comfortable comparing languages &#8211; utility, style, imperative vs. declarative, functional etc.?</li>
<li>How did they react when they didn&#8217;t know something?</li>
<li>How did they work through something they didn&#8217;t know?</li>
</ul>
<p><em>Manager Interview:</em></p>
<p>Questions:</p>
<p>tell me about:</p>
<ul>
<li>The best manager (or managerial experience) you had. what did they do well?</li>
<li>The worst manager (or experience) you had. what did they do poorly?</li>
<li>How you learned a new technology</li>
<li>The most difficult challenge you faced (tech or non-tech) and how you overcame it</li>
<li>Your proudest moment on the job</li>
<li>Working solo / in a small group / in a big group &#8212; what do you like about each?</li>
<li>Working with teams outside of development (design/qa/etc.)</li>
<li>Working with customers</li>
<li>Leading on projects/features</li>
<li>Working with task/bug tracking systems</li>
<li>Aan improvement you would like to have made or did make at your last job</li>
<li>Your experience with using/creating standards or best practices</li>
</ul>
<p>Analysis:</p>
<ul>
<li>How did the candidate work with others? Were those interactions portrayed in a positive light?</li>
<li>How driven are they (can they help you make the changes you want to make)?</li>
<li>Where they are on the lone wolf scale/mad scientist scale?</li>
</ul>
<p><em></em> </p>
<p>The goal with the following interview is to evaluate the candidate&#8217;s knowledge on a variety of topics. If their resume indicates they have four years of experience programming Asp.net, do they know what you&#8217;d expect them to know?</p>
<p><em>Technical Interview (inital question list from Scott Hanselman <a href="http://www.hanselman.com/blog/WhatGreatNETDevelopersOughtToKnowMoreNETInterviewQuestions.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hanselman.com');">here</a>):</em></p>
<p>Questions:</p>
<p>Web Infrastructure:</p>
<ul>
<li>How many processes can listen on a single TCP/IP port?</li>
<li>What is a PostBack?</li>
<li>Juxtapose the HTTP verbs GET and POST. What data is contained in each?</li>
<li>What kind of data is passed via HTTP Headers?</li>
<li>What is HEAD in an html document?</li>
<li>Explain how cookies work. Give an example of Cookie abuse.</li>
<li>What are the basic html elements that can be placed within the &lt;body&gt; tag?</li>
<li>How is a user session maintained by the server?</li>
</ul>
<p>Basic ASP.Net:</p>
<ul>
<li>When you’re running a component within ASP.NET, what process is it running within on Windows XP? Windows 2000? Windows 2003?</li>
<li>What is ViewState? How is it encoded? Is it encrypted? Who uses ViewState?</li>
<li>What three Session State providers are available in ASP.NET 1.1? What are the pros and cons of each?</li>
<li>What is the difference between a Server Control and a User control? What is a composite control?</li>
<li>Put the following events in order for a postback of an aspbutton server control:<br />
Page_init(), Page_load(), button_onclick()</li>
<li>What is the web.config used for?</li>
<li>Describe a method to implement paging of a set of records without rerunning the query for each page request. Where can the data be stored?</li>
<li>What are the options to handle unhandled exceptions in ASP.Net?</li>
<li>What is the difference between ClientId and Id of a web control?</li>
<li>What are the difference column types of a datagrid?</li>
<li>How do you set the client side onclick event of a control from the code behind?</li>
<li>How does a checkboxlist render?</li>
<li>How do you dynamically put javascript on a page? Where do you store the javascript in your project?</li>
</ul>
<p>Advanced ASP.Net:</p>
<ul>
<li>What is the difference between XML Web Services using ASMX and .NET Remoting using SOAP?</li>
<li>Are threads reused in ASP.NET between reqeusts? Does every HttpRequest get its own thread? Should you use Thread Local storage with ASP.NET?</li>
<li>Is the [ThreadStatic] attribute useful in ASP.NET? Are there side effects? Good or bad?</li>
<li>Give an example of how using an HttpHandler could simplify an existing design that serves Check Images from an .aspx page.</li>
<li>Describe how a browser-based Form POST becomes a Server-Side event like Button1_OnClick.</li>
<li>What kinds of events can an HttpModule subscribe to? What influence can they have on an implementation? What can be done without recompiling the ASP.NET Application?</li>
<li>Explain the importance of HttpRequest.ValidateInput()</li>
<li>How would one implement ASP.NET HTML output caching, caching outgoing versions of pages generated via all values of q= except where q=5 (as in <a href="http://localhost/page.aspx?q=5" onclick="javascript:pageTracker._trackPageview('/outbound/article/localhost');">http://localhost/page.aspx?q=5</a>)?</li>
<li>Explain &lt;@OutputCache%&gt; and the usage of VaryByParam, VaryByHeader, VaryByCustom work?</li>
<li>Suppose you’re setting javascript functions to control events dynamically. What javascript problems can occur when the page is downloading?</li>
<li>What must be true of all objects placed in the session?</li>
<li>Suppose you have a datagrid with a template column. The template column contains an asplinkbutton. How can you find a reference to this button in the datagrid’s ItemDataBound Event? Why would the asplinkbutton not be found for a particular row?</li>
</ul>
<p>Basic OO Developer stuff:</p>
<ul>
<li>Describe what an Interface is and how it’s different from a Class. Contrast the use of an abstract base class against an interface?</li>
<li>What is Reflection?</li>
<li>What is the difference between a.Equals(b) and a == b? In the context of a comparison, what is object identity versus object equivalence?</li>
<li>What is boxing?</li>
<li>Explain the differences between public, protected, private and internal (friend in VB)</li>
</ul>
<p>Basic Windows Stuff:</p>
<ul>
<li>Describe the difference between a Thread and a Process?</li>
<li>What is the difference between an EXE and a DLL?</li>
<li>What technology enables out-of-proc communication in .NET?</li>
</ul>
<p>Basic DotNet Stuff:</p>
<ul>
<li>What is strong-typing versus weak-typing? Which is preferred? Why?</li>
<li>What is the GAC? What problem does it solve?</li>
<li>Conceptually, what is the difference between early-binding and late-binding?</li>
<li>How is a strongly-named assembly different from one that isn’t strongly-named?</li>
<li>Can DateTimes be null?</li>
<li>What are PDBs? Where must they be located for debugging to work?</li>
<li>Why is catch(Exception) almost always a bad idea?</li>
<li>What is the difference between a Debug and Release build? Is there a significant speed difference? Why or why not?</li>
<li>Does JITting occur per-assembly or per-method? How does this affect the working set?</li>
<li>Is string a value type or a reference type?</li>
<li>Explain the use of virtual, sealed, override, and abstract (C#) or MustOverride, NotInheritable, Overrides, MustInherit (VB.Net)</li>
<li>What is the difference between: catch(Exception e){throw e;} and catch(Exception e){throw;}</li>
<li>What is the difference between typeof(foo) and myFoo.GetType()?</li>
<li>What is a static (Shared in VB) method?</li>
<li>What is this (Me in VB)? Can this be used within a static method?</li>
<li>What data structures does the .Net framework provide for working with data from a database?</li>
<li>What are some options to store database connection settings?</li>
</ul>
<p>Advanced DotNet Stuff:</p>
<ul>
<li>What is the difference between Finalize() and Dispose()?</li>
<li>What is the JIT? What is NGEN? What are limitations and benefits of each?</li>
<li>What’s wrong with a line like this? DateTime.Parse(myString);</li>
<li>How does the XmlSerializer work?</li>
<li>By what mechanism does NUnit know what methods to test?</li>
<li>What is remoting? How is it different than DCOM? When is it used?</li>
<li>What are the advantages and disadvantages to using the SOAP formatter vs. the binary formatter for serialization? What the advantages and disadvantages to implementing ISerializable for a class?</li>
<li>Are collections serializable? Are they threadsafe? Are exceptions serializable?</li>
</ul>
<p>ASP.NET Ajax:</p>
<ul>
<li>What is Ajax?</li>
<li>What is ASP.NET AJAX?</li>
<li>What role does the ScriptManager play?</li>
<li>Can we use multiple ScriptManager on a page?</li>
<li>What is the role of a ScriptManagerProxy?</li>
<li>What are the requirements to run ASP.NET AJAX applications on a server?</li>
<li>Can I use ASP.NET AJAX with any other technology apart from ASP.NET?</li>
<li>How can you cancel an Asynchronous postback?</li>
<li>Difference between Server-Side AJAX framework and Client-side AJAX framework?</li>
<li>Explain the UpdatePanel?</li>
<li>Explain the behavior/extender model. What does it provide over older asp.net javascript implementations.</li>
<li>How can you debug ASP.NET AJAX applications?</li>
<li>Can we call Server-Side code (C# or VB.NET code) from javascript?</li>
<li>Can you nest UpdatePanel within each other?</li>
<li>How is the page performance affected by multiple update panels?</li>
<li>How can you to add JavaScript to a page when performing an asynchronous postback?</li>
<li>Use the ScriptManager class. This class contains several methods like the RegisterStartupScript(), RegisterClientScriptBlock(), RegisterClientScriptInclude(), RegisterArrayDeclaration(),RegisterClientScriptResource(), RegisterExpandoAttribute(), RegisterOnSubmitStatement()</li>
<li>Explain differences between the page execution lifecycle of an ASP.NET page and an ASP.NET AJAX page</li>
<li>Explain the AJAX Client life-cycle events.</li>
<li>Is the ASP.NET AJAX Control Toolkit(AjaxControlToolkit.dll) installed in the Global Assembly Cache?</li>
</ul>
<p>Database Development (MS SQL oriented):</p>
<ul>
<li>What is a stored procedure? When would you use one?</li>
<li>What is a view? When would you use one?</li>
<li>What is the difference between a stored procedure and a view?</li>
<li>Write a query with a simple join between two tables that have a one to many relationship.</li>
<li>What is a temporary table? What are the different types of temporary tables? Why should one try to avoid using them?</li>
<li>What is the purpose of the Having clause? What is the purpose of the Group by clause?</li>
<li>Suppose you have a large text field in a table with many rows. Give examples of solutions to searching text fields in MS MSQL</li>
<li>When do we use the UPDATE_STATISTICS command?</li>
<li>Which TCP/IP port does SQL Server run on?</li>
<li>Can you tell me the difference between DELETE &amp; TRUNCATE commands?</li>
<li>What is the purpose of the transaction log?</li>
<li>What is BCP? When do we use it?</li>
<li>What is referential integrity? What are the advantages of it?</li>
<li>What is database normalization?</li>
<li>What are two different kinds of indices in MS SQL?</li>
<li>What is the basic functions for master, msdb, tempdb databases?</li>
</ul>
<p>Analysis:</p>
<ul>
<li>Did the candidate&#8217;s knowledge match up to their resume?</li>
<li>Did the candidate know the underlying technologies of the frameworks they used? Were they interested in learning?</li>
<li>How well did the candidate express themselves? Did they ever say they didn&#8217;t know something? Did they try to work through any questions?</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/05/04/more-thoughts-on-interviews/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Client-Side Template</title>
		<link>http://www.blogfor.net/2009/03/13/simple-client-side-template/</link>
		<comments>http://www.blogfor.net/2009/03/13/simple-client-side-template/#comments</comments>
		<pubDate>Sat, 14 Mar 2009 04:45:00 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nant]]></category>
		<category><![CDATA[asp.net ajax]]></category>
		<category><![CDATA[telerik]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=81</guid>
		<description><![CDATA[I needed an easy way to move a singleton chunk of HTML around the page.  More specifically i needed to insert an event driven piece of HTML into the telerik rad tree view node.  All i needed to do was, 1. create a DIV, the template,  that i could move into other elements. 2. Create [...]]]></description>
			<content:encoded><![CDATA[<p>I needed an easy way to move a singleton chunk of HTML around the page.  More specifically i needed to insert an event driven piece of HTML into the <a href="http://www.telerik.com/products/aspnet-ajax/treeview.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.telerik.com');">telerik rad tree view</a> node.  All i needed to do was, 1. create a DIV, the template,  that i could move into other elements. 2. Create one hidden DIV to store the template when it isn&#8217;t being shown.  Javascript is pretty slick sometimes, er, atleast it works well for things like managing the DOM!  The few lines of code show the power of this control.</p>
<p>When you want to move the template around you can use the following methods.<br />
<strong> Usage </strong></p>
<pre name="code" class="javascript">//inserts the template into the content
var contentElement = $get("conatiner1");
contentElement.appendChild(Samples.Template.get_template());

//inserts the template into the hidden storage container.
Samples.Template.storeTemplate();</pre>
<p>One of the nice things is that i can attach eventhandlers onto the elements in the template and they remain after moving the template around the DOM. I&#8217;ve only tested this in IE6/7 and FF 2/3, but it works great!  Here is the asp.net ajax behavior which lets you manage the template through a singleton object.</p>
<p><strong> The Javascript Object </strong></p>
<pre name="code" class="javascript">Type.registerNamespace("Samples");

/////////////////////////
//  base class
////////////////////////
Samples.NodeTemplate = function(storageName, templateName) {
    this._storage = null;
    this._storageName = storageName;
    this._templateName = templateName;
};
Samples.NodeTemplate.prototype = {

    onDisabledChanged: function(disabled) { },

    get_template: function() {
        return $get(this._templateName);
    },

    get_storage: function() {
    ///
    /// returns an element where the template is hidden when not inserted into the tree
    ///
        if (!this._storage) {
            this._storage = $get(this._storageName);
        }
        return this._storage;
    },

    get_disabled: function() {
        return this._disabled;
    },
    set_disabled: function(value) {
        if (this._disabled != value) {
            this._disabled = value;
            this.onDisabledChanged(value);
        }
    },

    storeTemplate: function() {
    ///
    /// Finds the template container by id and returns it to the storage area
    ///
        this.get_storage().appendChild(this.get_template());

    }
};
Samples.NodeTemplate.registerClass('Samples.NodeTemplate');

/////////////////////////
//  Singleton Template class
////////////////////////
Samples._Template = function(storageName, templateName) {
    Samples._Template.initializeBase(this, [storageName, templateName]);
};
Samples._Template.prototype = {

    onDisabledChanged: function(disabled) {
        ///
        /// overridable method to handle any changes required on disabled
        ///
        this.get_iconElement().disabled = disabled;
    },

    get_iconElement: function() {
        //would prolly be best to use a helper method since childnodes '
        //differs on a per browser basis, but works for this example
        return this.get_template().childNodes[0];
    }
};
Samples._Template.registerClass('Samples._Template', Samples.NodeTemplate);
//creating instance with a hardcoded id
Samples.Template = new Samples._Template("storage", "template");</pre>
<p>Well, this code is setup to work with a pretty specific use case but the base class can be extended into a wide range of neat DOM manipulation tools.  This little template is used to choose a type and submit.  A simple use case, when you need to turn a region into edit mode you can use this little guy to act as your singleton edit region.  Moving it into place whenever you need to, of course you&#8217;ll still have to bind data and wire up event handlers, but that&#8217;s another blog.  The mark-up below shows it can handle asp.net controls, assuming they don&#8217;t change over runtime.  it&#8217;s also important to note that you&#8217;ll need to manage the clientstate, if you need to support postbacks anyways.</p>
<p><strong> The HTML </strong></p>
<pre name="code" class="html">
<form id="form1">
<div id="container1" style="border: 1px solid red; height: 50px; width: 450px;">
<input onclick="this.parentNode.appendChild(Samples.Template.get_template()); return false;" type="submit" value="move here" /></div>
<div id="container2" style="border: 1px solid blue; height: 50px; width: 450px;">
<input onclick="this.parentNode.appendChild(Samples.Template.get_template()); return false;" type="submit" value="no move it here" /></div>
<input onclick="Samples.Template.storeTemplate(); return false;" type="submit" value="store it away" />
<div id="storage" style="display: none;">
<div id="template">
<input id="generate" onclick="return false;" type="submit" value="Generate" />
<input id="cancel" onclick="return false;" type="submit" value="Cancel" /></div>
</div>
</form>
</pre>
<p>Two things i really like about this code.  1. The power of code is seen in the usage, the behavior is just an overweight static set of helper methods. 2. This feels good to use.  Sure, it could be optimized a ton, but i&#8217;m not going to for this blog. 3.Javascript singletons are always interesting.</p>
<p><a href="http://www.blogfor.net/wp-content/uploads/2009/03/nodetemplate2.zip"><br />
DOWNLOAD THE EXAMPLE CODE HERE</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/03/13/simple-client-side-template/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TinyMCE and .Net integration &#8211; validators, gotchas and workarounds</title>
		<link>http://www.blogfor.net/2009/02/21/tinymce-and-net-integration-validators-gotchas-and-workarounds/</link>
		<comments>http://www.blogfor.net/2009/02/21/tinymce-and-net-integration-validators-gotchas-and-workarounds/#comments</comments>
		<pubDate>Sat, 21 Feb 2009 17:25:46 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=62</guid>
		<description><![CDATA[Refactoring of the Moxiecode.TinyMCE.Web.TextArea to address several issues with encoding, validation, and multiple instances per page.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working with <a href="http://www.moxiecode.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.moxiecode.com');">MoxieCode&#8217;s</a> free wywiwyg editor <a href="http://tinymce.moxiecode.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/tinymce.moxiecode.com');">tinyMCE</a>. I made the switch from <a href="http://www.fckeditor.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.fckeditor.net');">fckEditor</a> because of tinyMCE&#8217;s incredible featureset, small footprint, strong userbase, and high degree of configurability.</p>
<p>For ASP.net developers there is a <a href="http://prdownloads.sourceforge.net/tinymce/tinymce_compressor_net_2_0_2.zip?download" onclick="javascript:pageTracker._trackPageview('/outbound/article/prdownloads.sourceforge.net');">package</a> that includes controls for integrating tinyMCE as a server control. The server control (Moxiecode.TinyMCE.Web.TextArea) suffers several flaws, specifically:</p>
<ul>
<li>On render the control traverses the page&#8217;s entire control hierarchy via the FindAllTinyMCEAreas method. It&#8217;s collects all instances on the page so that it can render a single inline script to initialize the page clientside and load all the proper plugins. This traveral of all objects in the Page.Controls object graph can be very costly and the inline javascript  (tinyMCE.init(&#8230;)) is rendered before the first instance&#8217;s markup.</li>
<li>The control does not support encoding on postback &#8211; the tinyMCE control supports it client side, but on postback the server control does not decode it.</li>
<li>The control does not support asp.net validation.</li>
<li>Individual instances are not independently configurable. The initialization script uses the distinct union of all settings applied to all instances.</li>
</ul>
<p>So I refactored the control to fix these issues.</p>
<ul>
<li>I used the Page.Items dictionary to allow each instance to register itself, avoiding the control tree traveral. </li>
<li>By integrating with the scriptManager&#8217;s methods each instance of the tinyMCE control is initialized with specific settings. As with the original control, initial settings are &#8220;inherited&#8221; from the tinyMCE settings section of the web.config . The &#8220;installPath&#8221; is always the same across all instances. All other settings are overriden via the Settings collection or as attributes of the control&#8217;s markup.</li>
<li>The control now supports decoding input that was encoded clientside to work with asp.net request validation. It&#8217;s worth noting that if the tinyMCE setting &#8220;ask&#8221; equals true, then the tinyMCE editor may not be initialized when postback occurs. If the tinyMCE editor is not initialized, the contents of the textArea will not be encoded and on postback a request validation exception could be thrown.</li>
<li>The control now supports asp.net validation using custom validators. Before validation occurs, &#8220;tinyMCE.triggerSave(); &#8220; needs to be called to force the tinyMCE instances to flush their values to their respective textAreas.  I&#8217;ve included custom required and maxLength validators demonstrating this. They are of dubious use, however, since the markup is html encoded it is difficult to check the validitity of a textarea&#8217;s length or it&#8217;s content.For example, &#8221;&lt;p&gt;&lt;/p&gt;&#8221; is visually equivalent to &#8220;&#8221; in the browser. As a javascript string &#8221;&lt;p&gt;&lt;/p&gt;&#8221; is considered non-null (length &gt; 0) and it&#8217;s encoded text &#8220;&amp;lt;p&amp;gt;&amp;lt;p&amp;gt;&#8221; is 18 characters long. Though it renders as &#8220;&#8221; in the browser, the requiredValidator returns true and the maxLength validator will validate against a length of 18 characters.</li>
</ul>
<p>Check the code out <a rel="attachment wp-att-63" href="http://www.blogfor.net/2009/02/21/tinymce-and-net-integration-validators-gotchas-and-workarounds/tinymce-net-integration/" >here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/02/21/tinymce-and-net-integration-validators-gotchas-and-workarounds/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some thoughts on jQuery</title>
		<link>http://www.blogfor.net/2009/01/29/some-thoughts-on-jquery/</link>
		<comments>http://www.blogfor.net/2009/01/29/some-thoughts-on-jquery/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 03:44:06 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=55</guid>
		<description><![CDATA[Like many .net shops, my team has chosen jQuery for its javascript framework. We chose it because most of the team is very new to javascript and jQuery is both accessible and powerful. We&#8217;re looking to add client side functionality (mostly UI effects) without concern for cross browser compatibilities.  Modal popups, custom validation, and UI effects are all popular [...]]]></description>
			<content:encoded><![CDATA[<p>Like many .net shops, my team has chosen jQuery for its javascript framework. We chose it because most of the team is very new to javascript and jQuery is both accessible and powerful. We&#8217;re looking to add client side functionality (mostly UI effects) without concern for cross browser compatibilities.  Modal popups, custom validation, and UI effects are all popular uses of jQuery for us.</p>
<p>Javascript coding is big <a href="http://en.wikipedia.org/wiki/Paradigm_shift" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">paradigm shift</a> for Asp.net developers. The standard Asp.net tools (viewstate, update panels, postbacks) complicate even the simplest javascript. Simple operations like:</p>
<ul>
<li>dynamically instantiating javascript objects from the server</li>
<li>binding behaviors to controls with runat=&#8221;server&#8221; (dynamically determined client ids)</li>
<li>making asynchronous web service calls</li>
<li>reference resource files before they&#8217;re needed &#8211; e.g. ensure that the $ function is defined before calling $(document).ready(&#8230;)</li>
</ul>
<p>Like other javascript frameworks, jQuery provides some methods for finding and manipulating elements in the DOM. It also provides support for basic ajax calls, array manipulation, and event binding. In essence, it&#8217;s 10% helper methods (event binding, collection traversal) and 90% visual effects.</p>
<p>jQuery&#8217;s API abstracts away entirely the concept of &#8220;<a href="http://www.razorspeed.com/blog/2008/09/13/javascript-execution-context-closure-eval-and-this-keyword.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.razorspeed.com');">execution context</a>&#8220;. This concept makes javascript fundamentally different from C# and therefore makes javascript less accessible to C# developers.  Without it, however, jQuery doesn&#8217;t provide support for object oriented programming because the developer cannot set the context in which a method will execute. This in turn leads developers to write spaghetti code by binding various DOM events to essentially static functions.</p>
<p>Suppose for example that we have the following requirements:</p>
<ol>
<li>Show a page with a textbox and a button called &#8220;show modal&#8221;.</li>
<li>When the button is clicked, show a modal window with an &#8220;OK&#8221; and a &#8220;Cancel&#8221; button.</li>
<li>In the modal window, show the content of the textbox.</li>
<li>When the user clicks &#8220;Ok&#8221; call a web service and pass the value of the textbox.</li>
<li>When the user clicks &#8220;Cancel&#8221; hide the modal window.</li>
</ol>
<p>The requirements don&#8217;t seem that difficult to implement at first &#8211; using the jQuery API we can bind to the click events of the &#8220;Show Modal&#8221;, &#8220;Ok&#8221;, and &#8220;Cancel&#8221; buttons using inline javascript e.g.</p>
<pre name="code" class="javascript">$(document).ready(function(){$('OkButton').bind('click',...)}</pre>
<p>Note: each function will need to reference at least one DOM element. e.g. the &#8220;Ok&#8221; button needs to reference the modal window in order to hide it.</p>
<p>What happens, though when our requirements change? For example:</p>
<ul>
<li>The &#8220;Show Modal&#8221; button is used multiple times on the page.</li>
<li>Based on state/permission the &#8220;Show Modal&#8221; functionality should be disabled.</li>
<li>The button controls have &#8220;runat=server&#8221; on them and therefore have a dynamically determined client id.</li>
<li>The page needs to lookup information (possibly via web service) based on the value in the textbox and include that information in the modal window.</li>
</ul>
<p>As the client side logic becomes more complicated the need to encapsulate the logic into an object(s) grows &#8211; a central place for the logic of binding/unbinding events and handling. In javascript methods acquire state through closures &#8211; a combination a function a context (state)  - jQuery just isn&#8217;t made to do this.</p>
<p>jQuery doesn&#8217;t help novice javascript developers learn javascript. It empowers us to create web 2.0 applications with no knowledge beyond web 1.0.</p>
<p>Consider the common pattern event binding pattern in jQuery :</p>
<pre name="code" class="javascript">$("a").click(function () {
    alert("Hello World");
});</pre>
<p>What happens when the jQuery library hasn&#8217;t been downloaded yet? There&#8217;s now a race condition between this code being rendered and the jQuery library being referenced.</p>
<p>Here&#8217;s another pattern commonly used in jQuery for object initialization:</p>
<pre name="code" class="javascript">
(function($) { $.plugin = function(data) {... some initialization...})(jQuery);
</pre>
<p>As soon as the file containing this text is referenced in the page, the plugin is defined and initialized. As a pattern, we&#8217;ve now tightly coupled library definition and object instantiation. This works well when initializing singleton objects, but doesn&#8217;t work when instantiating multiple objects of the same type, perhaps using the object&#8217;s <a href="http://www.javascriptkit.com/javatutors/proto2.shtml" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.javascriptkit.com');">prototype</a> definition.</p>
<p>jQuery&#8217;s focus on a static API and lack of support for classes or execution context changes make it somewhat limited for broader application development. The <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">MS Ajax Extensions</a> and <a href="http://script.aculo.us/" onclick="javascript:pageTracker._trackPageview('/outbound/article/script.aculo.us');">prototype</a> frameworks already provide these capabilities. They also provide the backbone for the <a href="http://www.codeplex.com/AjaxControlToolkit" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeplex.com');">Ajax Control Toolkit</a> and <a href="http://script.aculo.us/" onclick="javascript:pageTracker._trackPageview('/outbound/article/script.aculo.us');">script.aculo.us</a> respectively. While jQuery is more accessible than these other frameworks, it comes at the cost of learning and leveraging javascript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2009/01/29/some-thoughts-on-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating Class Libraries of Asp.Net Web Components</title>
		<link>http://www.blogfor.net/2008/11/03/creating-class-libraries-of-aspnet-web-components/</link>
		<comments>http://www.blogfor.net/2008/11/03/creating-class-libraries-of-aspnet-web-components/#comments</comments>
		<pubDate>Tue, 04 Nov 2008 04:08:59 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=48</guid>
		<description><![CDATA[Investigation into creating a class libraries to hold Asp.net pages, user controls, server control, and web services.]]></description>
			<content:encoded><![CDATA[<p>Suppose you have multiple client projects and want to build a reusable framework for them. This framework could include components to build sites (server controls, data control fields, custom datagrid, custom pager etc.). It could also include components such as pages, user controls, and web services.</p>
<p>Scott Gu espouses a strategy for creating user control libraries <a href="http://webproject.scottgu.com/CSharp/UserControls/UserControls.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/webproject.scottgu.com');">here</a>, <a href="http://weblogs.asp.net/scottgu/archive/2006/08/16/Tip_2F00_Trick_3A00_-Creating-Sub_2D00_Web-Projects-using-the-VS-2005-Web-Application-Project-Option.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">here</a>, and <a href="http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">here</a>. The technique involves copying the makrup files from the library &#8220;project&#8221; to the client &#8220;project&#8221; using xcopy (robocopy on vista). There are additional articles like this <a href="http://www.codeproject.com/KB/aspnet/ConvertUserToCustom.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codeproject.com');">one</a> describing even more ways to achieve partial solutions to this problem.</p>
<p>Depending on your development and deployment needs the solution to this problem will vary. In this article I&#8217;ll go through some of the choices available their related trade-offs, give sample applications demonstrating various approaches, and show another method to do this without copying markup files by referencing only the fully compiled library site.</p>
<p>If your library is developed as a <a href="http://msdn.microsoft.com/en-us/library/ms178463(VS.80).aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">web site</a> you can leverage the edit-and-continue feature to create and debug components more quickly. Conversely, since there is no assembly associated with a web site, a <a href="http://blogs.msdn.com/webdevtools/archive/2008/01/25/announcing-rtw-of-visual-studio-2008-web-deployment-projects-wdp.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">web deployment project</a> is needed before components can be referenced in a client application.</p>
<p><em>Note: In order for components in the app_code directory of the library assembly to be accessible to the client application, library assembly must be referenced by the client application</em> and <em>the setting &#8220;Treat As Library Component (remove the App_Code.compiled file)&#8221; must be selected in the web deployment project.</em></p>
<p>By copying the component files to the client application, the library components containing markup are in effect being compiled as part of the client application. This can, however, lead to some issues.</p>
<p>If the web deployment project has &#8220;Allow this precompiled site to be updateable&#8221; checked, the build will remove the markup from aspx and ascx files and replace them with the text &#8220;This is a marker file generated by the precompilation tool, and should not be deleted!&#8221;. When the client application builds, Visual Studio tries to build these marker files and  fails on build with an error similar to &#8220;The page must have a &lt;%@ webservice class=&#8221;MyNamespace.MyClass&#8221; &#8230; %&gt; directive.&#8221;</p>
<p>When copying the markup files directly from the library &#8220;project&#8221; the files may contain a &#8220;codeFile&#8221; attribute which will not exist in the client application, causing a compiler warning. Alternatively, when the markup files are copied from the web deployment project&#8217;s output, the codeFile attribute has been removed but the compiler will now warn &#8220;c:\&#8230;\v2.0.50727\Temporary ASP.NET Files\&#8230;\App_Web_x4mc84hf.0.cs(134,53): warning CS0108: &#8216;ASP.library_usercontrols_libraryusercontrol_ascx.Profile&#8217; hides inherited member &#8216;LibrarySite.Library.UserControls.LibraryUserControl.Profile&#8217;. Use the new keyword if hiding was intended.&#8221; This is because the web application project already compiled part of the markup into the library assembly, namely the &#8220;Profile&#8221; and &#8220;ApplicationInstance&#8221; properties.</p>
<p>To enable web deployment compilation of the client application, the markup files must be copied from the library project (with the codeFile attribute) and not from the web deployment project output, otherwise Aspnet_compile will error.</p>
<p>Another common error is &#8220;Compiler Error Message: CS0433: The type &#8216;ASP.library_usercontrols_libraryusercontrol_ascx&#8217; exists in both &#8216;c:\&#8230;\v2.0.50727\Temporary ASP.NET Files\&#8230;\App_Web_empkj51o.dll&#8217; and &#8216;c:\&#8230;\v2.0.50727\Temporary ASP.NET Files\&#8230;\assembly\&#8230;\LibrarySite.DLL&#8217;&#8221; This again stems from the re-compilation of library controls in the client application when the client application already references the library assembly. It stems from a situation where the user control/page/webservice has been compiled in the library assembly and is compiled into the client application with the same type name.</p>
<p>A sample of this setup where the library is a web site can be found <a href="http://www.blogfor.net/wp-content/uploads/2008/11/websitelibrarywebsiteclient.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/11/websitelibrarywebsiteclient.zip');">here</a> (Client application is a vs2k8 web site) and <a href="http://www.blogfor.net/wp-content/uploads/2008/11/websitelibrarywebapplicationprojectclient.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/11/websitelibrarywebapplicationprojectclient.zip');">here</a> (Client application is a vs2k8 <a href="http://msdn.microsoft.com/en-us/library/aa983474.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">web application project</a>).</p>
<p>A sample of this setup where the library is a web application project can be found <a href="http://www.blogfor.net/wp-content/uploads/2008/11/webapplicationprojectlibrarywebsiteclient.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/11/webapplicationprojectlibrarywebsiteclient.zip');">here</a> (Client application is vs2k8 web site) and <a href="http://www.blogfor.net/wp-content/uploads/2008/11/webapplicationprojectlibrarywebapplicationprojectclient.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/11/webapplicationprojectlibrarywebapplicationprojectclient.zip');">here</a> (Client application is a vs2k8 web application project).</p>
<p>If you&#8217;re using subversion, one final approach to this method involves using svn <a href="http://svnbook.red-bean.com/en/1.0/ch07s03.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/svnbook.red-bean.com');">externs</a>.  An extern link to a child directory of the library is created from a child directory of the client application. When the Client application was compiled, it would also compile these files. Since the client application does not reference the library assembly, there is no type conflict and the controls are only compiled once.</p>
<p>This solution does not work for web services and is quite inflexible.</p>
<p>The basic problem with these approaches is the recompilation of the library controls and the tedious copying of the markup files.</p>
<p>A more flexible approach is to fully compile the library into a single assembly and reference it from the client application as a standard assembly. The problem now is to make the pages, user controls, and web services available to the client application.</p>
<p>In .net 2.0, user controls can be referenced by assembly and namespace in addition to url via the <a href="http://msdn.microsoft.com/en-us/library/ewtd66a0.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">LoadControl</a> method. When referencing precompiled user controls, the key is to reference the compiled markup class, not the codebehind (ASP.library_usercontrols_libraryusercontrol_ascx instead of LibrarySite.Library.UserControls.LibraryUserControl).</p>
<p>To reference pages and web services in the library assembly we need to update our configuration to map requests to these resources to the correct handlers.</p>
<p>In HttpHandlers section of the client application web.config we replace the existing handlers for aspx and asmx as follows:</p>
<pre name="code" class="xml"><span style="font-size: x-small;"><span style="font-size: x-small; color: #000000;">&lt;remove verb="*" path="*.asmx"/&gt;
&lt;remove verb="*" path="*.aspx"/&gt;</span></span>

<span style="font-size: x-small;"><span style="font-size: x-small; color: #000000;">&lt;add verb="*" path="*.aspx" type="LibrarySite.PageHandlerFactory, LibrarySite" validate="true" /&gt;
&lt;add verb="*" path="*.asmx" validate="false" type="LibrarySite.AutoDiscoveryWebServiceHandlerFactory, LibrarySite"/&gt;</span></span></pre>
<p>Now all http requests for .aspx and .asmx files will go through custom <a href="http://msdn.microsoft.com/en-us/library/system.web.ihttphandlerfactory.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">IHTTPHandlerFactories</a> to dynamically load pages and web services from the library assembly as necessary. The IHTTPHandlerFactories receives requests and tries to match them to the resource against the full type names in loaded assemblies (e.g. <a href="http://localhost/ClientSite/LibrarySite.Library.Pages.LibraryPage.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/localhost');">http://localhost/ClientSite/LibrarySite.Library.Pages.LibraryPage.aspx</a> will cause the IHTTPHandlerFactory to load and execute the page LibrarySite.Library.Pages.LibraryPage). If it is unable to find a match, the IHTTPHandlerFactory returns the result of the base (standard) IHTTPHandlerFactory.</p>
<p>The web service implementation for this came from this fantastic posting on codeproject: <span style="font-size: x-small; color: #008000;"><span style="font-size: x-small; color: #008000;"><a href="http://secure.codeproject.com/KB/cpp/WebserviceAndJavaProxy.aspx?display=Print" onclick="javascript:pageTracker._trackPageview('/outbound/article/secure.codeproject.com');">http://secure.codeproject.com/KB/cpp/WebserviceAndJavaProxy.aspx?display=Print</a>. <span style="color: #000000;">The author took great care to ensure his solution worked with JSON enabled web services which is very helpful.</span></span></span></p>
<p>In contrast to the web services code, the IHTTPHandlerFactory is much simpler:<br />
Note: the framework caches the mappings between virtualPath and the IHTTPHandler returned so the probe for matching page handlers is only done once per virtualPath.</p>
<pre name="code" class="csharp">public override IHttpHandler GetHandler(HttpContext context, string requestType, string virtualPath, string path)
{
 // Try to get the type associated with the request (On a name to type basis)
 Type pageType = this.GetPageServiceType(Path.GetFileNameWithoutExtension(path));
 // if we did not find any send it on to the original ajax script service handler.
 if (pageType == null)
 {
  return base.GetHandler(context, requestType, virtualPath, path);
 }
 else
 {

  return (Page)Activator.CreateInstance(pageType);
 }
}

  /// &lt;summary&gt;
  /// Searches all Services and tries to find a class with the specified name
  /// &lt;/summary&gt;
  private Type GetPageServiceType(string pageTypeName)
  {
   // Todo: Caching mechanism for assembly checks
   foreach (Assembly loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
   {
    Type basePageType = loadedAssembly.GetType(pageTypeName);
    if (basePageType != null)
    {
     var services = from t in loadedAssembly.GetTypes()
           where t.IsSubclassOf(basePageType)
            select t;
     var pageType = services.FirstOrDefault();
     if (pageType != null)
     {
      return pageType;
     }
    }
   }
   return null;
  }</pre>
<p>A working sample of all of this is <a href="http://www.blogfor.net/wp-content/uploads/2008/11/websitelibrarywebsiteclientnomarkupfiles.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/11/websitelibrarywebsiteclientnomarkupfiles.zip');">here.</a></p>
<p><span style="font-size: x-small; color: #008000;"><span style="font-size: x-small; color: #008000;"><span style="font-size: x-small; color: #008000;"></span></span></span></p>
<p> </p>
<p> </p>
<p><span style="font-size: x-small; color: #008000;"></span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/11/03/creating-class-libraries-of-aspnet-web-components/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Migrating Asp.Net SiteMaps to MS SQL (or fun with MS SQL XML functions)</title>
		<link>http://www.blogfor.net/2008/10/20/migrating-aspnet-sitemaps-to-ms-sql-or-fun-with-ms-sql-xml-functions/</link>
		<comments>http://www.blogfor.net/2008/10/20/migrating-aspnet-sitemaps-to-ms-sql-or-fun-with-ms-sql-xml-functions/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 02:06:46 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=45</guid>
		<description><![CDATA[As part of a larger project, my recent work has involved migrating Asp.Net sitemaps from Xml to MS SQL in order to use a modified version of the SqlSiteMapProvider. 
Using the xml processing functions new in MS SQL 2005, sitemap files can be imported ease.
A &#8220;regular&#8221; sitemap file is going to look like this:

&#60;siteMap&#62;
  &#60;siteMapNode [...]]]></description>
			<content:encoded><![CDATA[<p>As part of a larger project, my recent work has involved migrating Asp.Net <a href="http://msdn.microsoft.com/en-us/library/yy2ykkab.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">sitemaps</a> from Xml to MS SQL in order to use a modified version of the <a href="http://msdn.microsoft.com/en-us/magazine/cc163657.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SqlSiteMapProvider</a>. <br />
Using the <a href="http://msdn.microsoft.com/en-us/library/ms345115.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">xml processing functions</a> new in MS SQL 2005, sitemap files can be imported ease.</p>
<p>A &#8220;regular&#8221; sitemap file is going to look like this:</p>
<pre name="code" class="xml">
&lt;siteMap&gt;
  &lt;siteMapNode title="Home" description="Home" url="~/default.aspx" SomeProperty="someValue"&gt;
    &lt;siteMapNode title="Products" description="Our products"
      url="~/Products.aspx"  SomeProperty="someValue"  SomeOtherProperty="someOtherValue"&gt;
      &lt;siteMapNode title="Hardware" description="Hardware choices"
        url="~/Hardware.aspx" SomeThirdProperty="someThirdValue"/&gt;
      &lt;siteMapNode title="Software" description="Software choices"
        url="~/Software.aspx" /&gt;
    &lt;/siteMapNode&gt;
    &lt;siteMapNode title="Services" description="Services we offer"
        url="~/Services.aspx"&gt;
        &lt;siteMapNode title="Training" description="Training classes"
          url="~/Training.aspx" /&gt;
        &lt;siteMapNode title="Consulting" description="Consulting services"
          url="~/Consulting.aspx" /&gt;
        &lt;siteMapNode title="Support" description="Supports plans"
          url="~/Support.aspx" /&gt;
    &lt;/siteMapNode&gt;
  &lt;/siteMapNode&gt;
&lt;/siteMap&gt;
</pre>
<p>using the script <a href='http://www.blogfor.net/wp-content/uploads/2008/10/populate-sitemap-table-from-xml.sql'>here</a> we can populate a table (created with this <a href="http://www.blogfor.net/wp-content/uploads/2008/10/create-sitemap-table.sql" >script</a>). </p>
<p><em>Note: siteMap nodes can contain custom <a href="http://msdn.microsoft.com/en-us/library/system.web.sitemapnode.attributes.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">additional attributes</a>. This script inserts these attributes into the AdditionalProperties column as xml elements:<br />
</em></p>
<pre name="code" class="xml">
    &lt;siteMapNode title="Products" description="Our products"
      url="~/Products.aspx"  SomeProperty="someValue"  SomeOtherProperty="someOtherValue"&gt;
</pre>
<p>becomes</p>
<pre name="code" class="xml">
&lt;row name="SomeProperty" value="someValue"/&gt;
&lt;row name="SomeOtherProperty" value="someOtherValue"/&gt;
</pre>
<p>The bulk of the work is down in this query:</p>
<pre name="code" class="sql">
select T.c.value('@url', 'nvarchar(255)') as url
, T.c.value('@title', 'nvarchar(255)') as title
, isnull(T.c.value('@description', 'nvarchar(255)'), '') as description
,
	(select U.c.value('local-name(.)', 'varchar(255)') as name , U.c.value('.', 'varchar(255)') as value
	from T.c.nodes('@*[local-name(.) != "url" and local-name(.) != "title" and local-name(.) != "description"]') U(c)
	FOR XML RAW
)
as AdditionalProperties
,T.c.value('../@url', 'nvarchar(255)') as parentUrl
from @xml.nodes('/siteMap//siteMapNode') T(c);
</pre>
<p>First we parse the xml variable into &#8220;rows&#8221; using the nodes() function to query to for all the &#8220;siteMapNode&#8221; elements.<br />
To build the &#8220;AdditionalProperties&#8221; value for an element node, we do the following:<br />
Parse the element attributes into rows using the XPath query &#8220;@*&#8221;.<br />
Filter out attribute rows with already defined names (url, title, etc.)<br />
Combine the result set of attributes again into a single entry using the &#8220;FOR XML RAW&#8221; statement. </p>
<p><em>Note: this uses the MS SQL functions for untyped XML. If the config has an xmlns attribute, it must be removed before running the script.</em><br />
To verify the results, run the following query and compare the results to the source config file:</p>
<pre name="code" class="sql">with TMP ([id]
      ,[Title]
      ,[Description]
      ,[Url]
      ,[Roles]
      ,[Parent]
      ,[Sequence]
      ,[AdditionalProperties]
	  ,level)
as (
	SELECT [id]
      ,[Title]
      ,[Description]
      ,[Url]
      ,[Roles]
      ,[Parent]
      ,[Sequence]
      ,[AdditionalProperties]
	  ,0 as level
  FROM [SiteMap] as a
  where parent is null
  union all
	SELECT a.[id]
      ,a.[Title]
      ,a.[Description]
      ,a.[Url]
      ,a.[Roles]
      ,a.[Parent]
      ,a.[Sequence]
      ,a.[AdditionalProperties]
	  ,TMP.level + 1 as level
  FROM [SiteMap] as a
  inner join TMP on a.parent = TMP.id
)
select * from Tmp
order by level, sequence
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/10/20/migrating-aspnet-sitemaps-to-ms-sql-or-fun-with-ms-sql-xml-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding the Javascript language from a .Net based background</title>
		<link>http://www.blogfor.net/2008/09/22/understanding-the-javascript-language-from-a-net-based-background/</link>
		<comments>http://www.blogfor.net/2008/09/22/understanding-the-javascript-language-from-a-net-based-background/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 02:43:02 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=43</guid>
		<description><![CDATA[Ever wonder why the Microsoft samples for Ajax always call Function.createDelegate? Why IE6 has such bad memory leak problems? Ever wonder what &#8220;this&#8221; in javascript refers to?
Javacript is dynamic and interpreted.  Superficially this means that:

all objects have a dictionary of properties. One can then modify this dictionary in a very tangible if not intuitive sense by [...]]]></description>
			<content:encoded><![CDATA[<p>Ever wonder why the Microsoft samples for Ajax always call Function.createDelegate? Why IE6 has such bad memory leak problems? Ever wonder what &#8220;this&#8221; in javascript refers to?</p>
<p>Javacript is <a href="http://en.wikipedia.org/wiki/Dynamic_programming_language" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">dynamic</a> and <a href="http://en.wikipedia.org/wiki/Interpreted_language" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">interpreted</a>.  Superficially this means that:</p>
<ul>
<li>all objects have a dictionary of properties. One can then modify this dictionary in a very tangible if not intuitive sense by simply setting properties on the object.<br />
var x = [];<br />
x.someProperty = 1;</li>
<li>the dictionary of properties can be enumerated like a collection<br />
for (var property in object) {..}</li>
<li>arrays are really just objects with properties, the &#8220;key&#8221; in the dictionary is the array index<br />
var x = <span class="objectBox objectBox-text">{0:&#8221;test&#8221;}</span> ;<br />
is the same as<br />
x = ["test"];</li>
<li>one can use the &#8220;eval&#8221; statement to translate and execute any string of code<br />
var p;<br />
eval(&#8221;p=1&#8243;);<br />
will set p equal to one.</li>
</ul>
<p>There are, however, some more basic questions whose answer is not quite obvious such as:</p>
<ul>
<li>how does one implement inheritance?</li>
<li>what does &#8220;this&#8221; refer to?</li>
<li>what is the difference between calling a shared method and an instance method? How does one denote one versus the other?</li>
<li>how do I bind an html element&#8217;s event to an event handler method on my object?</li>
<li>how do I bind an object event to an event handler method on another object?</li>
</ul>
<p>Most developers assume that Javascript is merely the scripting equivalent of java, but that is not so. To quote Douglas Crockford (JavaScript Architect at Yahoo!):</p>
<blockquote><p>JavaScript&#8217;s C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.</p></blockquote>
<p>Coming from a .net background, I really don&#8217;t remember much about Lisp from college &#8211; I remember lists, lots of parentheses, and thinking &#8220;It&#8217;s all about recursion&#8221;. One key feature of Javascript is the <a href="http://en.wikipedia.org/wiki/Closure_(computer_science)" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">closure</a>. To quote wikipedia:</p>
<blockquote><p>a closure is a function that is evaluated in an environment containing one or more bound variables. When called, the function can access these variables.</p></blockquote>
<p>A good explanation with examples can be found <a href="http://www.javascriptkit.com/javatutors/closures.shtml" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.javascriptkit.com');">here</a>. In javascript one can still create object oriented code with private and public methods. It is not, however, intuitive to do so. Opposite from .net, standard class methods are public and accessible as static members. Closures are what gives us state in our methods by binding variables to objects when the method is executed, particularly the &#8220;this&#8221; object based on context.</p>
<p>In ASP.Net, one adds an event handler like so:<br />
textBox.TextChanged += new EventHandler(SomeObject.TextChangedHandler);</p>
<p>In order for this to work, &#8220;SomeObject&#8221; must be instantiated and the TextChanged event bound to &#8220;SomeObject&#8221;. </p>
<p>Suppose instead that I could create a new method like so:</p>
<p>textBox.TextChanged += new Function(sender,eventArgs=&gt;some other code)</p>
<p>In this case I don&#8217;t need to initialize an object or create a static method to handle the TextChanged event. Instead I create an anonymous function and databind the sender and eventArgs parameters to the caller and the caller&#8217;s event args.</p>
<p>This is exactly what Javascript has been doing since IE5. The coding emphasis is now on the function to handle the event using databound variables rather than forcing the developer to go through hoops to instantiate objects and wire up methods on those objects. The mechanism that lets you do this is the closure.</p>
<p>Closures lead to certain issues, however, specifically the <a href="http://en.wikipedia.org/wiki/Funarg_problem" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">funarg</a> problem.  Simplify stated a closure may contain a reference to almost any object on the heap. The garbage collector now has to determine if an object is referenced by any closures before destruction. The amount of additional work reqiured for reference counting and object graph traversal is monstrous.</p>
<p>The garbage collection algorithm used by IE6 has been notorious for <a href="http://support.microsoft.com/kb/929874" onclick="javascript:pageTracker._trackPageview('/outbound/article/support.microsoft.com');">leaking memory due to poor garbage collection</a>. In November 2007, Microsoft finally recognized the <a href="http://support.microsoft.com/kb/830555/" onclick="javascript:pageTracker._trackPageview('/outbound/article/support.microsoft.com');">problem</a> and released a partial <a href="http://support.microsoft.com/kb/929874/en-us" onclick="javascript:pageTracker._trackPageview('/outbound/article/support.microsoft.com');">fix</a>. Microsoft notes <a href="http://msdn.microsoft.com/en-us/library/bb250448.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">here</a> that:</p>
<blockquote><p>New Web applications live up to higher standards. A page might run for hours without being navigated and retrieve updated information dynamically through Web services. Language features are pushed to the breaking point by combining complex event schemes, object-oriented JScript, and closures to produce entire applications. With these and other changes, certain memory leak patterns are becoming more prominent, especially those previously hidden by navigation.</p>
<p>The good news is that memory leak patterns can be easily spotted if you know what to look for. Most of the troublesome patterns you might face have known workarounds requiring only a small amount of extra work on your behalf. While some pages might still fall prey to small memory leaks, the most noticeable ones can be easily removed&#8230;.</p>
<p>Closures are a specific form of circular reference that pose the largest pattern to existing Web application architectures. Closures are easy to spot because they rely on a specific language keyword and can be searched for generically</p></blockquote>
<p>If Javascript is more like scheme or Lisp than Java, then perhaps just learning a new syntax isn&#8217;t enough to properly code Javascript. Take a moment and check out Douglas Crockford&#8217;s <a href="http://www.crockford.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.crockford.com');">site</a>, particularly his javascript <a href="http://javascript.crockford.com/survey.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/javascript.crockford.com');">tutorial</a> and javascript <a href="http://javascript.crockford.com/javascript.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/javascript.crockford.com');">history</a>. The more you learn about Javascript, the more you will realize how vastly different it is from any Microsoft technology prior to .net 3.5.  You&#8217;ll also get a much better idea how the language constructs of .net 3.5 (lambda expressions, closures, extensions, etc.) are revolutionary in bringing some of the power and flexibility of dynamic languages into static ones without sacrificing compile time type checking and performance.</p>
<p>What is easy and clean in javascript (using the prototype library):</p>
<blockquote><p>originalList.findAll<span class="brackets">(</span><span class="keywords">function</span><span class="brackets">(p</span><span class="brackets">)</span> {<br />
  <span class="keywords">return</span> p.Age &gt; 50;<br />
}<span class="brackets">)</span></p></blockquote>
<p>Is now just as easy in .net 3.5:</p>
<blockquote><p>results = origionaList.Where(p=&gt;p.Age &gt; 50).ToList();</p></blockquote>
<p>If you&#8217;re working on a javascript heavy application, take the time to learn about the language and to lever its inherent features rather than try and bend it to a static language paradigm.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/09/22/understanding-the-javascript-language-from-a-net-based-background/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Testing HTTP Handlers And Modules Without A Web Server</title>
		<link>http://www.blogfor.net/2008/09/22/testing-http-handlers-and-modules-without-a-web-server/</link>
		<comments>http://www.blogfor.net/2008/09/22/testing-http-handlers-and-modules-without-a-web-server/#comments</comments>
		<pubDate>Tue, 23 Sep 2008 02:05:19 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=44</guid>
		<description><![CDATA[Recently I came across this posting at Cozi Tech Blog:

A Way To Unit Test ASP.NET IHttpHandler Implementations


If you find yourself writing simple HTTP handler code that produces and consumes structured data (for instance, some RESTful application), you may wonder how to test it without fiddling with IIS or configuration files. Here&#8217;s a trick to write pure [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I came across this <a href="http://blogs.cozi.com/tech/2008/05/a-way-to-unit-t.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.cozi.com');">posting</a> at Cozi Tech Blog:</p>
<blockquote>
<h3 class="entry-header">A Way To Unit Test ASP.NET IHttpHandler Implementations</h3>
<div class="entry-content">
<div class="entry-body">
<p>If you find yourself writing simple HTTP handler code that produces and consumes structured data (for instance, some RESTful application), you may wonder how to test it without fiddling with IIS or configuration files. Here&#8217;s a trick to write pure unit tests that verify your <code>IHttpHandler</code> implementation does what you expect. By &#8220;pure unit tests&#8221;, I mean test code that:</p>
<ul>
<li>works without configuration files (like web.config);</li>
<li>needs no servers (like Cassini, IIS, or your own mock HTTP server with full ASP.NET pipeline that you were about to write and debug just before you stumbled upon this article);</li>
<li>doesn&#8217;t access file system (like ashx files);</li>
</ul>
</div>
</div>
<li>avoids globals (like <code>HttpContext.Current</code>).<br />
&#8230;</li>
</blockquote>
<p>At the core of the post is the <a href="http://msdn.microsoft.com/en-us/library/system.web.hosting.simpleworkerrequest.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');"><span style="color: #000000;">System.Web.Hosting.S</span>impleWorkerRequest</a> object in the System.Web.Hosting namespace. It provides an easy way to create http requests and pass them to a handler. The posting gives a nice example and referencing a  <a href="http://code.google.com/p/codebackpack/source/browse/tags/how-to-test-httphandlers/src/TestHttp/WorkerRequestStub.cs" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');">custom version of SimpleWorkerRequest</a> on google code.</p>
<p>The SimpleWorkerRequest implementation referenced has a small bug with querystring values and is limited in scope. Some additional things I wanted to test were HTTP Headers (expiration, mime type, etc.) and file attachments. To test these things, modify WorkerRequestStub to override <a href="http://msdn.microsoft.com/en-us/library/system.web.httpworkerrequest.sendresponsefromfile.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SendResponseFile</a>, <a href="http://msdn.microsoft.com/en-us/library/system.web.httpworkerrequest.sendunknownresponseheader.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SendKnownResponseHeaders</a>, and <a href="http://msdn.microsoft.com/en-us/library/system.web.httpworkerrequest.sendknownresponseheader.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">SendUnknownResponseHeaders</a> to track and expose the headers and file submissions to the testing container.</p>
<p>While testing web based UIs is still a difficult and expensive problem there&#8217;s no reason testing web services should be.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/09/22/testing-http-handlers-and-modules-without-a-web-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Properly using the &#8220;references&#8221; parameter to the MS Ajax $create statement</title>
		<link>http://www.blogfor.net/2008/08/10/properly-using-the-references-parameter-to-the-ms-ajax-create-statement/</link>
		<comments>http://www.blogfor.net/2008/08/10/properly-using-the-references-parameter-to-the-ms-ajax-create-statement/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 15:24:29 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=39</guid>
		<description><![CDATA[the MS Ajax framework provides a built in method to initialze extenders and wire up references between them. Unfortunately, there is very little documentation on how to do so. This is my quick example.]]></description>
			<content:encoded><![CDATA[<p>Suppose you want to reference a component from another component. The MS Ajax documentation gives the following explanation of the <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Global/CreateShortcutMethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">$create</a> function:</p>
<blockquote>
<h2>Syntax</h2>
<div class="code">
<pre>$create(<span class="parameter">type, properties, events, references, element</span>);</pre>
</div>
<h2 class="subsectionTitle">Arguments</h2>
<table class="authoredTable" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
<tr>
<td><span class="parameter">type</span></td>
<td>The type of the component to create.</td>
</tr>
<tr>
<td><span class="parameter">properties</span></td>
<td>(Optional) A JSON object that describes the properties and their values.</td>
</tr>
<tr>
<td><span class="parameter">events</span></td>
<td>(Optional) A JSON object that describes the events and their handlers.</td>
</tr>
<tr>
<td><span class="parameter"><strong>references</strong></span></td>
<td><strong>(Optional) A JSON object that describes the properties that are references to other components.</strong></td>
</tr>
<tr>
<td><span class="parameter">element</span></td>
<td>(Optional) The DOM element that the component must be attached to.</td>
</tr>
</tbody>
</table>
</blockquote>
<p>The documentation doesn&#8217;t provide much information, however, on why you should use the references parameter instead of just using the <a href="http://www.asp.net/AJAX/documentation/live/ClientReference/Global/FindShortcutMethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">$find</a> method in the initialize event of your component.</p>
<p>When the framework renders <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Global/CreateShortcutMethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">$create</a> statements through the <a href="http://www.asp.net/AJAX/Documentation/Live/overview/ScriptManagerOverview.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">scriptmanager</a>,  each script descriptor becomes a $create statement in the page source. These statements are executed by the ajax framework when page_load. In order for a component instance to reference another component instance, the object being referenced has to exist already.  If the $create statement for the object being referenced comes after the referencing component&#8217;s $create, an error will occur when the $find method is called.</p>
<p>One way around this is to execute $find every time that the component needs to be referenced. This has performance implications and doesn&#8217;t scale well when dealing with collections of components.</p>
<p>Another way around this is to use the MS Ajax <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys/ApplicationClass/SysApplicationLoadEvent.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">Application_load event</a> using code similar to the following:</p>
<pre name="code" class="javascript">MyNamespace.MyComponent.prototype = {
 initialize: function() {
  MyNamespace.MyComponent.callBaseMethod(this, 'initialize');

  this._applicationLoadHandler = Function.createDelegate( this, this.applicationLoad );
  Sys.Application.add_load( this._applicationLoadHandler );
  
 },

 applicationLoad: function(sender, e) {
 
  this._componentReference = $find(this._componentReferenceId);
  //Remove the LoadHandler 
  Sys.Application.remove_load( this._applicationLoadHandler );
  this._applicationLoadHandler = null;
 },
 
 set_ComponentReferenceId : function( value ) {
  this._componentReferenceId = value;
 },
  
 get_ComponentReferenceId : function() {
  return this._componentReferenceId;
 }
 // other code
}</pre>
<p>This approach is explicit and therefore more clear to other developers who might inherit your code. Additionally for collections of components, this method is an excellent option.</p>
<p>The framework does, however, does provide a way to ensure that when the initialize method is called, the component references have already been set just like other component properties.</p>
<p>If our custom component inherits from AjaxControlToolkit.ExtenderControlBase, we can add the AjaxControlToolkit.ComponentReference attribute to the property declaration</p>
<pre name="code" class="c#">&lt;AjaxControlToolkit.RequiredProperty()&gt; _
&lt;AjaxControlToolkit.ExtenderControlProperty()&gt; _
&lt;IDReferenceProperty()&gt; _
&lt;AjaxControlToolkit.ComponentReference()&gt; _
&lt;AjaxControlToolkit.ClientPropertyName("ComponentReference")&gt; _
Public Property ComponentReferenceId() As String
 Get
  Return GetPropertyValue(Of String)("ComponentReferenceId", String.Empty)
 End Get
 Set(ByVal value As String)
  SetPropertyValue(Of String)("ComponentReferenceId", value)
 End Set
End Property
</pre>
<p><i>Note: we also need to change the getter/setter methods in the javascript to:</i></p>
<blockquote><p>set_ComponentReference : function( value ) {<br />
  this._componentReference = value;<br />
},<br />
get_ComponentReference : function() {<br />
  return this._componentReference;<br />
}</p></blockquote>
<p>Before the initialize method is called the framework will now call set_ComponentReference and pass $find(value from the server side property) as the sole parameter.</p>
<p>If you&#8217;re not extending from AjaxControlToolkit.ExtenderControlBase, you can perform the same operation by using the SetComponent method in the GetScriptDescriptors method:</p>
<pre name="code" class="c#">Protected Overrides Function GetScriptDescriptors(ByVal targetControl As System.Web.UI.Control) As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptDescriptor)
 Dim descriptor As New ScriptBehaviorDescriptor("MyNamespace.MyComponent", targetControl.ClientID)
 descriptor.AddComponentProperty("ComponentReference",Me.ComponentReference)
 ...
 Return New ScriptDescriptor() {descriptor}
End Sub</pre>
<p>In either event, the net result should be a statment similar to the following generated by the framework in the page source:</p>
<blockquote><p>Sys.Application.add_init(function() {<br />
    $create(MyNamespace.MyComponent, {&#8230;,&#8221;id&#8221;:&#8221;CustomComponentId&#8221;}, null, $find(&#8221;RefefencedBehaviorId&#8221;), $get(&#8221;targetControlId)&#8221;));<br />
});</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/properly-using-the-references-parameter-to-the-ms-ajax-create-statement/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Binding MS Ajax Extenders to nested Controls</title>
		<link>http://www.blogfor.net/2008/08/10/binding-ms-ajax-extenders-to-nested-controls/</link>
		<comments>http://www.blogfor.net/2008/08/10/binding-ms-ajax-extenders-to-nested-controls/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 15:17:58 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=40</guid>
		<description><![CDATA[How to use the AjaxControlToolkit.ExtenderControlBase's method "ResolveControlProperty" to locate controls contained inside other naming containers.]]></description>
			<content:encoded><![CDATA[<p>The MS Ajax Extender model encourages us to bind html elements to extender properties via clientId. To help make this more declarative, the ajax control toolkit provides property attributes to do this <a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/Walkthrough/ExtenderClasses.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">mapping</a> between server side control property and client side javascript accessor methods:</p>
<blockquote><p><span style="font-size: 10pt; font-family: 'Courier New';">[<span style="color: #008080;">IDReferenceProperty</span>(<span style="color: #0000ff;">typeof</span>(<span style="color: #008080;">WebControl</span>))] </span><br />
<span style="FONT-SIZE: 10pt"><span style="font-family: 'Courier New';">[<span style="color: #008080;">DefaultValue</span>(<span style="color: #0000ff;">""</span>)]<br />
[<span style="color: #008080;">ExtenderControlProperty</span>]<br />
[<span style="color: #008080;">ClientPropertyName("popupElement")</span>]<br />
[<span style="color: #008080;">ElementReference</span>]<br />
[<span style="color: #008080;">ExtenderControlProperty</span>]<br />
</span></span><br />
<span style="font-size: 10pt; color: #0000ff; font-family: 'Courier New';">public</span><span style="font-size: 10pt; font-family: 'Courier New';"> <span style="color: #0000ff;">string</span> PopupControlID { � }</span></p></blockquote>
<p><span style="font-size: x-small; font-family: Courier New;">In this case, the framework will call a method on the javascript extender called &#8220;set_popupElement&#8221; and pass it the result of $get(&#8221;value from PopupControlId on the server side&#8221;).</span></p>
<p><span style="font-size: x-small; font-family: Courier New;">This method works well until you want to bind the extender against elements contained in a different naming container. For example, suppose you create a custom extender to populate a popup panel depending on what link a user clicks upon. </span></p>
<p><span style="font-size: x-small; font-family: Courier New;">Assume the popup panel control is in fact an asp.net panel. Since panel implements <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">INamingContainer</a>, the custom extender will not locate any elements inside it because the extender&#8217;s parent control (the one whose childControls collection it searches) is not the panel itself. Since FindControl() is not recursive, when the extender tries to find the controls inside the panel by Id, it will be unable to locate them. </span></p>
<p><span style="font-size: x-small; font-family: Courier New;">One limited workaround is to move the extender inside the asp.net panel. This will work until the extender has to resolve controls both inside and outside the popup panel.</span></p>
<p><span style="font-size: x-small; font-family: Courier New;">Another workaround is to set the element ids in the code behind. </span></p>
<blockquote><p><span style="font-size: x-small; font-family: Courier New;">MyExtender.PopupControlId = this.PopupPanel.FindControl(&#8221;elementToBindAgainst&#8221;);</span></p></blockquote>
<p> this can be quite tedious depending on the number of controls you want to bind against and is less intuitive than the declarative approach.</p>
<p>Assuming the extender inherits from AjaxControlToolkit.ExtenderControlBase, a more flexible method is to override the ResolveControlProperty method as follows:</p>
<pre name="code" class="c#"> public string SearchContainerPaths { get; set; }

  private bool searchControlsInitialized;
  private System.Collections.Generic.List&lt;Control&gt; searchContainers = new System.Collections.Generic.List&lt;Control&gt;();
  protected void ResolveControlProperty(object sender, ResolveControlEventArgs e)
  {
   if (string.IsNullOrEmpty(e.ControlID))
   {
    return;
   }

   if (!this.searchControlsInitialized) //check tosee if we've built the "probe" collection of containers to search
   {
    char[] splitChar = new char[] {'.'};
    string[] controlPaths = this.SearchContainerPaths.Split(new char[] {','});
    foreach (string path in controlPaths) {
     string[] subPaths = path.Split(splitChar);
     Control ctl = this.Parent;
     foreach (string controlId in subPaths)
     {
      ctl = ctl.FindControl(controlId);
      if (ctl == null)
      {
       throw new ArgumentException("Cannot find path:" + path);
      }
     }
     this.searchContainers.Add(ctl);
    }
    searchControlsInitialized = true;
   }
   Control tmpCtl = null;
   foreach (Control control in this.searchContainers)
   {
    tmpCtl = control.FindControl(e.ControlID);
    if (tmpCtl != null)
    {
     e.Control = tmpCtl; //the control is found, set it and exit.
     break;
    }
   }
   if (tmpCtl == null) //unable to find control in map paths, throw an exception.
   {
    throw new ArgumentException("Cannot find controlId: " + e.ControlID);
   }
  }</pre>
<p>By setting SearchContainerPaths we can now probe for any controls outside the immediate naming container e.g. SearchContainerPaths=&#8221;panel1.panel2,modalPanel&#8221; will search the controls collection of panel2 (contained in panel1) and the controls collection of modalPanel.</p>
<p>This <a href="http://www.blogfor.net/wp-content/uploads/2008/08/resolvecontrolpropertysample1.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wp-content/uploads/2008/08/resolvecontrolpropertysample1.zip');">sample</a> gives an example of this using the modalPopupBehavior and a customExtender to bind the popup panel.</p>
<p> </p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/binding-ms-ajax-extenders-to-nested-controls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perils of Sys.UI.Component and Update Panels</title>
		<link>http://www.blogfor.net/2008/08/10/perils-of-sysuicomponent-and-update-panels/</link>
		<comments>http://www.blogfor.net/2008/08/10/perils-of-sysuicomponent-and-update-panels/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 15:06:22 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=38</guid>
		<description><![CDATA[Howto avoid duplicate extender objects when using update panels and custom extenders.]]></description>
			<content:encoded><![CDATA[<p>When writing custom MS Ajax controls, deciding what framework class to inherit from on the client can be tricky. The MS Ajax <a href="http://www.asp.net/AJAX/Documentation/Live/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">documentation</a> gives the following explanation of the <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys/ComponentClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">Sys.UI.Component</a> and it&#8217;s associated child classes <a href="http://www.asp.net/AJAX/Documentation/Live/tutorials/CreatingCustomClientComponentsTutorial.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">here</a>:</p>
<table class="authoredTable" border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<th>Client component object types</th>
<th>Summary</th>
</tr>
<tr>
<td>Components</td>
<td>
<ul>
<li>Derive from the Component base class.</li>
<li>Typically have no UI representation, such as a timer component that raises events at intervals but is not visible on the page.</li>
<li>Have no associated DOM elements.</li>
<li>Encapsulate client code that is intended to be reusable across applications.</li>
</ul>
</td>
</tr>
<tr>
<td>Behaviors</td>
<td>
<ul>
<li>Derive from the Behavior base class, which extends the Component base class.</li>
<li>Extend the behavior of DOM elements, such as a watermarking behavior that can be attached to an existing text box.</li>
<li>Can create UI elements, although they do not typically modify the basic behavior of the DOM element that they are associated with.</li>
<li>If assigned an ID, can be accessed directly from the DOM element through a custom attribute (expando).</li>
<li>Do not require an association with another client object, such as a class derived from the Control or Behavior classes.</li>
<li>Can reference either a control or a non-control HTML element in their <a href="http://www.blogfor.net/ClientReference/Sys.UI/BehaviorClass/BehaviorElementProperty.aspx" >element</a> property.</li>
</ul>
</td>
</tr>
<tr>
<td>Controls</td>
<td>
<ul>
<li>Derive from the Control base class, which extends the Component base class.</li>
<li>Represent a DOM element as a client object, typically changing the original DOM element&#8217;s ordinary behavior to provide new functionality. For example, a menu control might read <span class="keyword">&lt;li&gt;</span> items from a <span class="keyword">&lt;ul&gt;</span> element as its source data, but not display a bulleted list.</li>
<li>Are accessed from the DOM element directly through the control expando.</li>
</ul>
</td>
</tr>
</tbody>
</table>
<p>If the difference between Behaviors and Controls isn&#8217;t clear to you, you&#8217;re not alone. In fact, depending on the version of microsoft documentation, or their horrific <a href="http://go.microsoft.com/fwlink/?LinkId=116063" onclick="javascript:pageTracker._trackPageview('/outbound/article/go.microsoft.com');">msdn documentation</a>, these terms are used almost interchangeably. Generally, behavior, extender, control all refer to the same thing &#8211; some custom code written in javascript and instantiated via $create.</p>
<p>Following the documentation then, if an extender does not have a target control it should inherit from Sys.UI.Component.</p>
<p>Suppose we have a page that&#8217;s using update panels and depending on the user action an extender (inheriting from Sys.UI.Component) is written to the page.</p>
<p>When a postback occurs the extender will be rendered to the page again. Now there will be a new extender and an existing extender both with the same id. This will cause a javascript error that&#8217;s hard to track down, something like &#8220;Behavior with Id:? already exists&#8221;.</p>
<p>The original instance of the extender should have been disposed when the update panel framework reloaded the page. Since the extender didn&#8217;t have a target element (the core difference between Sys.UI.Component and Sys.UI.Behavior), the framework didn&#8217;t know to dispose the extender object when the update panel refreshed its content. </p>
<p>To work around this, simply change the extender to inherit from Sys.UI.Behavior and giving it a target element. This will ensure that the object is disposed when the target element is disposed when either the update panel framework destroys the target element or the page is unloaded.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/perils-of-sysuicomponent-and-update-panels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Converting VB to C# while preserving project references and existing solutions</title>
		<link>http://www.blogfor.net/2008/08/10/converting-vb-to-c-while-preserving-project-references-and-existing-solutions/</link>
		<comments>http://www.blogfor.net/2008/08/10/converting-vb-to-c-while-preserving-project-references-and-existing-solutions/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 14:59:05 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=37</guid>
		<description><![CDATA[Converting VB to C# on a large scale involves maintaining project and references properly. This post describes an easy way to do this to avoid rebuilding solutions and project references by hand after a conversion.]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve recently begun converting a tremendous amount of code from VB to C#.  Others have much better postings about the <a href="http://www.dnjonline.com/article.aspx?ID=mar05_vbvscsharp" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.dnjonline.com');">pros and cons</a> of chosing VB or C#.  The web is littered with religious rants from haughty C# developers (although they are in the <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.tiobe.com');">minority</a> of .net developers) about which managed language is <a href="http://discuss.joelonsoftware.com/default.asp?dotnet.12.369517.23" onclick="javascript:pageTracker._trackPageview('/outbound/article/discuss.joelonsoftware.com');">better</a>.</p>
<p>We chose VB originally because it was easier to develop against, it was a language the team was familiar with, and we didn&#8217;t have time to ramp both to .net 2.0 and all the quirks of C#. At the time, there were virtually no features of C# that we felt would make our work more efficient.  Over time, however, our team has changed &#8211; some of the original developers have moved on and some really smart people with a lot of strong C#/Java experience have joined us. We&#8217;ve also had two years to ramp up on .net 2.0 and are now moving on to 3.5 with enthusiasm.  Part of the point in moving to 3.5 is to leverage language features only available in C#.</p>
<p>The tool we selected for conversion is <a href="http://www.elegancetech.com/CSVB/CSVB.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.elegancetech.com');">C-Sharpener for VB.Net</a> because it converts projects in total and does <a href="http://www.elegancetech.com/CSVB/FAQ.aspx#HowWorks" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.elegancetech.com');">symbol comparison</a> on the output.  Minor quirks of the software include the following:</p>
<ol>
<li>in VB, int(5) means an array with upper-bound 5, but in C# int(5) means an array with 5 elements and upper-bound 4)</li>
<li>a small issue with complex generics- a dictionary whose value was also a generic does not convert properly</li>
<li>embedded resource references in C# require full names including directory path e.g. to access the embedded resource file name &#8220;MyResource.txt&#8221; in C#, we would need to call assembly.GetManifestResourceStream( &#8220;MyResourceFiles.SomeChildDirectory.MyResource.txt&#8221; ) as opposed to the seemingly simpler VB assembly.GetManifestResourceStream( &#8220;MyResource.txt&#8221; ).</li>
<li>namespace statements are parsed by period. &#8220;Namespace A.B.C&#8221; becomes<br />
namespace A<br />
{<br />
    namespace B<br />
    {<br />
        namespace C<br />
        {</li>
</ol>
<p>Once the project is converted, C-Sharpener gives adds the newly created C# project to your solution with the original project name and &#8220;_CS&#8221; appended to it.</p>
<p>In order to finish the conversion, we need make changes to unmodified versions solution (.sln file) via text editor.<br />
<em>note: C-Sharpener will change the solution when it runs to add the new C# project so be sure to revert the solution after the conversion.</em></p>
<p>Rather than go through every project&#8217;s references and update them to the GUID of the new project we&#8217;d like to simply reuse the GUID. This is relatively easy</p>
<ol>
<li>Open the source VB project&#8217;s vbproj file in a text editor and copy the inner text of the ProjectGuid element.</li>
<li>Open the csproj file of the newly created project in a text editor.</li>
<li>update the AssemblyNamespace and RootNamespace elements by removing the extra &#8220;_CS&#8221;</li>
<li>Update the &lt;ProjectGuid&gt; element &#8211; set the inner text of the element to the inner text of the ProjectGuid from the original vb project.</li>
<li>open all solutions containing the original vb project in a text editor.<br />
your vb project should be referenced in the file like so:Project(&#8221;{ProjectTypeGUID}&#8221;) = &#8220;MyAssembly&#8221;, &#8220;..\MyAssembly\MyAssembly.vbproj&#8221;, &#8220;{MyProjectGUID}&#8221;<br />
EndProject</li>
<li>update the path to the newly created cs projectProject(&#8221;{ProjectTypeGUID}&#8221;) = &#8220;MyAssembly&#8221;, &#8220;..\MyAssemblyInCSharp\MyAssembly.csproj&#8221;, &#8220;{MyProjectGUID}&#8221;<br />
EndProject</p>
<p><em>note: you&#8217;ll need to update the path to the csproj and make sure the GUID following it (MyProjectGUID) is the same as the one you pasted from the VB project.<br />
</em></li>
<li>The ProjectTypeGUID indicates to Visual Studio when it tries to compile your solution what kind of project it is &#8211; C#, VB, Cobol etc. for example, one of our solutions contains C#, VB, and web deployment projects. It looks like this:Project(&#8221;{F184B08F-C81C-45F6-A57F-5ABD9991F28F}&#8221;) = &#8220;VBProject&#8221;, &#8220;..\VBProject\VBProject.vbproj&#8221;, &#8220;{27509F53-2929-459A-8B1E-E03ADA1D8B36}&#8221;<br />
EndProject</p>
<p>Project(&#8221;{2CFEAB61-6A3B-4EB8-B523-560B4BEEF521}&#8221;) = &#8220;WebDeploymentProject&#8221;, &#8220;WebDeploymentProject.wdproj&#8221;, &#8220;{24F3E583-E313-48D6-92ED-A137AC83BBDB}&#8221;<br />
EndProject</p>
<p>Project(&#8221;{F184B08F-C81C-45F6-A57F-5ABD9991F28F}&#8221;) = &#8220;VBProject2&#8243;, &#8220;..\VBProject2\VBProject2.vbproj&#8221;, &#8220;{C73B5D28-96D6-4B29-B90D-E0E3788F0692}&#8221;<br />
EndProject</p>
<p>Project(&#8221;{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}&#8221;) = &#8220;CSharpProject&#8221;, &#8220;..\CSharpProject\CSharpProject.csproj&#8221;, &#8220;{D20CCA67-387E-4B1F-9232-1EEE1359CD9E}&#8221;<br />
EndProject</p>
<p>note how the second GUID in each project is unique. The first GUID is the one you need to change to tell the solution that the project is no longer a VB project but a C# one instead. For your project, update ProjectTypeGUID to the C# guid &#8211; FAE04EC0-301F-11D3-BF4B-00C04F79EFBC.</li>
</ol>
<p> </p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/converting-vb-to-c-while-preserving-project-references-and-existing-solutions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interface Segregation Principle, Asp.Net, Generics, Interfaces and Covariance, Oh my!</title>
		<link>http://www.blogfor.net/2008/08/10/interface-segregation-principle-aspnet-generics-interfaces-and-covariance-oh-my/</link>
		<comments>http://www.blogfor.net/2008/08/10/interface-segregation-principle-aspnet-generics-interfaces-and-covariance-oh-my/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 14:52:23 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=36</guid>
		<description><![CDATA[The interface segregation principle is something most asp.net developers tend to ignore. If I only have one consumer of my business layer (the web/UI layer) why bind against an interface instead of the actual business objects?
Recently at my job we found ourselves answering that question. We have a single code base and strong continuous integration. [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://c2.com/cgi/wiki?InterfaceSegregationPrinciple" onclick="javascript:pageTracker._trackPageview('/outbound/article/c2.com');">interface segregation principle</a> is something most asp.net developers tend to ignore. If I only have one consumer of my business layer (the web/UI layer) why bind against an interface instead of the actual business objects?</p>
<p>Recently at my job we found ourselves answering that question. We have a single code base and strong continuous integration. Binding to UI interfaces seemed to make things &#8220;less agile&#8221; :). Now that we&#8217;re live, however, things have changed. We&#8217;re willing to sacrifice the beautiful patterns we&#8217;ve held so dear for the pragmatic concerns of performance and scalability.</p>
<p>We analyzed our application for problems and began to work around some of our thornier speed issues by writing custom sql that could leverage vendor specific database features and using the caching features of the asp.net framework.</p>
<p>The problem is that our business entities are too heavy &#8211; these custom queries were faster in part because we didn&#8217;t need to retrieve all the data necessary to initialize an entity. Additionally, to avoid <a href="http://blogs.msdn.com/tess/archive/2008/05/28/asp-net-memory-thou-shalt-not-store-ui-objects-in-cache-or-session-scope.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">GC problems</a>, the data we wanted to cache needed to be much &#8220;lighter&#8221; without references to other objects or data context.</p>
<p>Our web code was now too rigid. It was binding against strongly typed business objects and needed to bind against interfaces to give us the flexibility and control re-use we needed. We therefore adjusted the necessary Asp.net controls that bound to entities to bind to interfaces instead.</p>
<p>A problem arose, however, when we went to bind lists. The problem is called <a href="http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');">covariance</a> and discussed very well <a href="http://blogs.msdn.com/rmbyers/archive/2005/02/16/375079.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">here</a> and compared with JAVA <a href="http://www.jprl.com/Blog/archive/development/2007/Aug-31.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.jprl.com');">here</a>. Basically, to optimize performance, the .net runtime emits code to strongly type collections. This new type has no ties to the interfaces or inheritance hierarchy of the type that it is templating e.g. If A is the base class of B and C, one cannot pass a List&lt;B&gt; to a method expecting a paramter of type List&lt;A&gt;.</p>
<p>The way around this is actually pretty simple. It&#8217;s how most asp.net controls work out of the box. A control&#8217;s <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.datasource.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">datasource</a> is simply an object. Only when <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.databind.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">DataBind()</a> is called is the datasource consumed, and then it&#8217;s consumed item by item in the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.onitemdatabound.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">ItemDataBound</a> event where there is no problem casting individual items of a datasource to an interface.</p>
<p>This paradigm works well. Though we can&#8217;t cast strongly typed generic lists based we can cast Foo to IFoo as we consume each item for databinding. The result is a more flexible UI with more code re-use and improved performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/interface-segregation-principle-aspnet-generics-interfaces-and-covariance-oh-my/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hallmarks of great developers</title>
		<link>http://www.blogfor.net/2008/08/10/hallmarks-of-great-developers/</link>
		<comments>http://www.blogfor.net/2008/08/10/hallmarks-of-great-developers/#comments</comments>
		<pubDate>Sun, 10 Aug 2008 14:45:52 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[general]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=26</guid>
		<description><![CDATA[At my current employer we&#8217;ve spent a long time trying to refine our hiring process. While the process is by no means ideal, after conducting dozens of interviews a few key indictators of great developers have emerged. While not requirements, the developers we&#8217;ve hired who are successful and continue to innovate, improvise, and impress all [...]]]></description>
			<content:encoded><![CDATA[<p>At my current employer we&#8217;ve spent a long time trying to refine our hiring process. While the process is by no means ideal, after conducting dozens of interviews a few key indictators of great developers have emerged. While not requirements, the developers we&#8217;ve hired who are successful and continue to innovate, improvise, and impress all share these qualities.</p>
<ol>
<li>Reading books.<br />
This one sounds simple. One applicant I spoke with said &#8220;Books make a good reference but I find online resources better for learning and keeping up with technology&#8221;. This misses the point entirely. Books are indeed a great reference &#8211; they&#8217;re more than just a quick answer to a shortlived technical problem. Books help you avoid bothersome technical hurdles in the first place. Jeff Atwood from <a href="http://www.codinghorror.com/blog" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codinghorror.com');">coding horror</a> expresses this much better <a href="http://www.codinghorror.com/blog/archives/001108.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codinghorror.com');">here</a>. My team and I spent almost a year working extensively with javascript and the ASP.Net AJAX framework before we ever read a book on the subject. Not suprisingly we learned more from reading the book than we had from all the online references and tutorials. Granted, we were much more receptive to the author&#8217;s ideas because we&#8217;d already struggled so much with the technology, but reading this <a href="http://www.manning.com/gallo/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.manning.com');">book</a> made us better developers by helping us connect existing dots and drawing new pictures.There are numerous excellent books out there about everything that software developers do. From <a href="http://www.amazon.com/Beautiful-Code-Leading-Programmers-Practice/dp/0596510047/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1210733699&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">books</a> that expand your horizons, <a href="http://www.amazon.com/Pragmatic-Programmer-Journeyman-Master/dp/020161622X/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1210733781&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">books</a> that help you write better code, <a href="http://www.amazon.com/Mythical-Man-Month-Software-Engineering-Anniversary/dp/0201835959/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1210733871&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">books</a> that give you perspective on the bigger picture, <a href="http://www.amazon.com/Software-Development-Principles-Patterns-Practices/dp/0135974445/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1210734092&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">books</a> on patterns and practices ,and even fictional <a href="http://www.amazon.com/Microserfs-Douglas-Coupland/dp/0060987049/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1210733965&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">books</a> that reinforce what I love about developing software.Many people go out and buy the bible for the next version of some framework or technology. The version they wish they were using, but never end up reading because it doesn&#8217;t apply to their work. People who take an interest in doing what they spend 40+ hours a week better are more likely to do a better job for you.</li>
<li>Subscribe to blogs and follow websites<br />
Blogs keep you abreast of developments in technology. There are really smart people out there with facinating things to say. Following particular blogs shows you have an interest in the world around you and want to see beyond your immediate perspective.Steve Yegge&#8217;s <a href="http://steve-yegge.blogspot.com/atom.xml" onclick="javascript:pageTracker._trackPageview('/outbound/article/steve-yegge.blogspot.com');">blog</a> is brilliant. It&#8217;s also opinionated and ignorant of all things microsoft, but he has a lot of really cogent thoughts. Scott Gu&#8217;s <a href="http://weblogs.asp.net/scottgu/rss.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">blog</a> is an invaluable resource to keep up with Microsoft technologies. For year&#8217;s Joel Spolsky has provided <a href="http://www.joelonsoftware.com/rss.xml" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.joelonsoftware.com');">original thoughts</a> on a wide variety of topics that software developers share in common. I&#8217;m glad these guys (and many others) share what they think because there&#8217;s a lot to learn from them.</li>
<li>Work to understand the frameworks that they use<br />
The following are interview questoins I&#8217;ve asked:</p>
<ul>
<li>How does the .net xmlSerializer work?</li>
<li>How does declarative databinding in the aspx markup work? e.g. &lt;%# DataBinder.Eval(Container.DataItem,&#8221;au_id&#8221;) %&gt;</li>
</ul>
<p>The questions themselves aren&#8217;t perfect judges of a developer&#8217;s caliber. They do, however, speak to other concerns- Are they using the framework(s) as designed? Is it all voodoo magic or do they know how it works? Before you can understand the limitations of a technology or framework you have to know how it works. Are dynamic languages better or worse than static languages? There are no right answer here, it depends on what you&#8217;re trying to do. <a href="http://memeagora.blogspot.com/feeds/posts/default" onclick="javascript:pageTracker._trackPageview('/outbound/article/memeagora.blogspot.com');">Neil Ford</a> (from Thoughtworks) said in a talk once that you should generally understand one level deeper than the the code you&#8217;re writing. If you&#8217;re using asp.net, how does the asp.net framework work? If you&#8217;re using a business layer, how does it retrieve and persist data? If you&#8217;re writing web pages, how do HTML, HTTP, and web servers work? Technology choices should be based on evidence and fact; learning how things work is a very basic part of that.</li>
<li>Find technology interesting and exciting in its own right<br />
Most of my time at work is spent with issues that involve code- developing software that is scalable, secure, and efficient while continually work more efficiently. I probably won&#8217;t use the next version of Java (I didn&#8217;t use the last one much either). I probably won&#8217;t make my living coding Ruby on Rails applications. That doesn&#8217;t mean that they don&#8217;t have interesting innovations, patterns, or paradigms. I love my job, I love doing my job well. Technologies that help me do my job better help make me better and that&#8217;s something to be excited about.</li>
</ol>
<p>The underlying quality in these traits is passion. People who love developing software, like learning, and want to improve as developers are people that we want to hire.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/08/10/hallmarks-of-great-developers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Optimize UpdatePanel performance by avoiding unnecessary element disposal</title>
		<link>http://www.blogfor.net/2008/05/27/optimize-updatepanel-performance-by-avoiding-unnecessary-element-disposal/</link>
		<comments>http://www.blogfor.net/2008/05/27/optimize-updatepanel-performance-by-avoiding-unnecessary-element-disposal/#comments</comments>
		<pubDate>Tue, 27 May 2008 23:45:40 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=23</guid>
		<description><![CDATA[When an update panel is loaded the asp.net client side framework iterates over all the dom elements and disposes any ajax controls bound to them.  This is a method to bypass the default behavior when there are no ajax controls contained in the update panel.]]></description>
			<content:encoded><![CDATA[<p>I fought using <a href="http://ajax.asp.net/docs/overview/UpdatePanelOverview.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/ajax.asp.net');">update panels</a> for a long time. Every time someone demonstrates the MS AJAX framework they skip the amazing features and go right to update panels. They&#8217;d say &#8220;Look how easy they are to use!&#8221;, &#8220;They integrate right into the code you have now.&#8221;, and my personal favorite, &#8220;This is how you can AJAX enabled your website&#8221;. I thought they were a heavy solution filled with problems like <a href="http://msdn2.microsoft.com/en-us/library/system.web.ui.page.smartnavigation.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">smartnav</a> has in asp.net 1.1.<br />
The MS AJAX framework is much more than just update panels. There&#8217;s more to writing AJAX enabled web sites than wrapping your dynamic content inside update panels.  However, there&#8217;s something I failed to realize- for what they do, update panels are the best tool for the job.  If the goal is to asynchronously update content in a page using the same code used to render the content in the first place, updates panels are it.  Less obvious features include:</p>
<ul>
<li>Only the data being refreshed is transmitted from the web server</li>
<li>UI code uses the same controls to render synchronously or asynchronously</li>
<li>The framework manages the loading of additional javascript and css references</li>
<li>The framework only renders update panels that have been triggered for refresh</li>
<li>There is a simple and effective way to specify which panels get updated on postback</li>
<li>Update panels work almost seamlessly with the other parts of the MS AJAX framework &#8211; components, controls, and behaviors</li>
</ul>
<p>I have now accepted the fact that Microsoft has put more thought, time and money into making update panels better than any homegrown solution.</p>
<p>In the primer <a href="http://www.manning.com/gallo/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.manning.com');">Asp.Net AJAX IN ACTION</a>, the authors take great care to explain precisely how update panels work.  They describe how the ajax framework creates and disposes <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys/ComponentClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">components</a> when an update panel&#8217;s contents are updated.  For every element in the update panel being disposed, the ajax framework checks to see if there are any <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/ControlClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">controls</a> or <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/BehaviorClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">behaviors</a> bound to the element that needs to be disposed.</p>
<p><em>Note: any components not bound to elements are not disposed when update panels are refreshed. When the page_unload() event calls the dispose method of the components an error may occur because the DOM state has changed and the components don&#8217;t reflect it.</em></p>
<p>Why bother with object disposal? Why not just replace the innerHTML of the update panel&#8217;s div?  <a href="http://www.julienlecomte.net/blog" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.julienlecomte.net');">Julien Lecompte</a> (from Yahoo!) explains a few issues <a href="http://www.julienlecomte.net/blog/2007/12/38/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.julienlecomte.net');">here</a>. Basically, expando attributes on elements cause memory leaks when not disposed properly. <a href="http://www.crockford.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.crockford.com');">Douglas Crockford</a> (also from Yahoo!) describes the basic <a href="http://www.crockford.com/javascript/memory/leak.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.crockford.com');">workaround</a>.  Fortunately for us, however, the Microsoft framework does this already in part through the component <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/BehaviorClass/BehaviorDisposeMethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">dispose</a> method.</p>
<p>When the update panel is about to be loaded, the framework doesn&#8217;t know which objects need to be disposed. It has to iterate over all the elements about to be destroyed and check for objects to dispose.  The following code is from MicrosoftAjaxWebForms.debug.js (comments in code are mine):</p>
<pre name="code" class="javascript">function Sys$WebForms$PageRequestManager$_updatePanel(updatePanelElement, rendering) {
	//some code not germane to this post has been omitted here
	//this is where the existing content is disposed
	this._destroyTree(updatePanelElement);
	//and the content is updated
	updatePanelElement.innerHTML = rendering;
}
function Sys$WebForms$PageRequestManager$_destroyTree(element) {
	if (element.nodeType === 1) {
		var childNodes = element.childNodes;
		for (var i = childNodes.length - 1; i &gt;= 0; i--) {
			var node = childNodes[i];
			if (node.nodeType === 1) {
				//if the node has a dispose method, call it
				if (node.dispose &amp;&amp; typeof(node.dispose) === "function") {
					node.dispose();
				}
				//if the node has a sys.ui.control associated with it, call its dispose method
				else if (node.control &amp;&amp; typeof(node.control.dispose) === "function") {
					node.control.dispose();
				}
				//check for sys.ui.behaviors associated with the node and call dispose on each one
				var behaviors = Sys.UI.Behavior.getBehaviors(node);
				for (var j = behaviors.length - 1; j &gt;= 0; j--) {
					behaviors[j].dispose();
				}
				//recurse the contents of this node to do it again
				this._destroyTree(node);
			}
		}
	}
}</pre>
<p>If you know there are no objects bound to the content of the update panel, Asp.Net AJAX In Action suggests that you can avoid the performance penalty imposed by the framework&#8217;s memory leak prevention. They suggest removing the update panel div from the DOM after the asynchronous result is returned and before the framework applies the result to the DOM. We can use the <a href="http://www.asp.net/AJAX/Documentation/Live/ClientReference/Sys.WebForms/PageRequestManagerClass/PageRequestManagerPageLoadingEvent.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">pageLoading</a> event to do this.</p>
<pre name="code" class="vb.net">'''
''' Exposes methods to increase update panel performance when the panel contains content without sys.ui.controls associated with it
'''
'''
Public NotInheritable Class UpdatePanelRemoveNodeOnPostback         

	'''
	''' returns string for script to remove the specified control on the client DOM before the page is loaded after an asyncronous postback
	''' this saves the atlas framework from having to traverse the existing dom elements and remove all behaviors, thereby increasing performance
	''' NOTE: THIS CAN ONLY BE USED WHEN THE CONTROL HAS NO CLIENT SIDE CONTROLS ASSOCIATED WITH IT, specifically, as is the case with some of our
	''' gridviews
	'''
	'''

	'''
	'''
	Public Shared Function CreateScriptToRemoveExistingNodeFromUpdatePanelBeforePageLoad(ByVal control As Control) As String
		Return String.Format(System.Globalization.CultureInfo.InvariantCulture, Resources.UpdatePanelRemoveNodeOnPageLoading.Script, control.ClientID, control.ClientID, control.ClientID)
	End Function
End Class</pre>
<p>The function references a script included as a resource:</p>
<pre name="code" class="javascript">&lt;script type="text/javascript"&gt;
	var pageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
	pageRequestManager.add_pageLoading(onPageLoading{0});        

	function onPageLoading{1}(sender, e) {
		var itemToRemove = $('{2}');
		if (itemToRemove != null) {
			itemToRemove.remove();
		}
	}
&lt;/script&gt;</pre>
<p>One common place I use this is when an update panel contains a gridview. This is an ideal candidate because the amount of html being disposed can be quite large. In the gridview&#8217;s container&#8217;s preRender event:</p>
<pre name="code" class="vb.net">Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
	MyBase.OnPreRender(e)
	If GridView.Visible Then
		Dim script As String = UpdatePanelRemoveNodeOnPostback.CreateScriptToRemoveExistingNodeFromUpdatePanelBeforePageLoad(GridView)
		Me.Page.ClientScript.RegisterStartupScript(Me.GetType, "RemoveGridViewPrePostBackLoad", script)
	End If
End Sub</pre>
<p>When the update panel is loaded, the javascript code will fire removing the gridview element from the DOM before the disposal code is fired.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/05/27/optimize-updatepanel-performance-by-avoiding-unnecessary-element-disposal/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Time based Caching in a Load Balanced ASP.Net Application</title>
		<link>http://www.blogfor.net/2008/05/27/time-based-caching-in-a-load-balanced-aspnet-application/</link>
		<comments>http://www.blogfor.net/2008/05/27/time-based-caching-in-a-load-balanced-aspnet-application/#comments</comments>
		<pubDate>Tue, 27 May 2008 23:33:17 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=24</guid>
		<description><![CDATA[One method to work around caching issue when an asp.net application scales from a single server to a web farm.]]></description>
			<content:encoded><![CDATA[<p>When using the <a href="http://msdn.microsoft.com/en-us/library/ms178597.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">asp.net application cache</a> a common problem occurs when the application scales from a single web server to a web farm. This problem and more are more broadly discussed <a href="http://msdn.microsoft.com/en-us/magazine/cc500561.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">here</a>.</p>
<p>One common approach to keep cache items in sync across web servers is use of <a href="http://msdn.microsoft.com/en-us/library/67z4z916.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">file dependencies</a> on a central file server. When a depenency file is modified, all web servers in the farm remove the dependent items from their cache.</p>
<p>This works well until one tries to cache an item for a specified duration <em>without</em> a specific file dependency.  Consider a web site that shows &#8220;recent blog posts&#8221;. The list may be constantly changing and although some latency of the data is allowed(hence the caching), <em>the data must always be consistent no matter which web server serves the response</em>.</p>
<p>We can use the same file dependency strategy to keep the cache items in sync between web servers. The &#8220;trick&#8221; is to produce a hash of the data to be cached and include that information when synchronizing the servers.</p>
<p>If a web server receives a request and does not have the data in its application cache, it must retrieve it.  The server then compares a hash of the data against the contents of a dependency file (unique to that cache item) accessible to all web servers. If the contents of the file are different than the hash generated, the latest results retrieved for the cache item do not match the cache items on other web servers. By replacing the contents of the cache item dependency file with the value of the new hash we can guarantee that the cache items on other web servers will be invalidated and removed.</p>
<p>A sample project demonstrating this is <a href="File URL">here</a>.</p>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/05/27/time-based-caching-in-a-load-balanced-aspnet-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Class Table Inheritance: An Investigation into SQL Performance</title>
		<link>http://www.blogfor.net/2008/05/27/class-table-inheritance-an-investigation-into-sql-performance/</link>
		<comments>http://www.blogfor.net/2008/05/27/class-table-inheritance-an-investigation-into-sql-performance/#comments</comments>
		<pubDate>Tue, 27 May 2008 23:29:01 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=30</guid>
		<description><![CDATA[Class Table Inheritance is a powerful tool when persisting a strong object oriented business model, but what happens when the data size grows?  If we know the type of object we&#8217;re selecting, the query is straightforward and performs well:
select
	 base_class.id
	,base_class.sub_type
	,inheriting_class.column1
..
	,inheriting_class.columnn
from
	base_class inner join inheriting_class on base_class.id = inheriting_class.base_class_id
Using multiple tables, requires an inner join to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.martinfowler.com/eaaCatalog/classTableInheritance.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.martinfowler.com');" target="_blank">Class Table Inheritance</a> is a powerful tool when persisting a strong object oriented business model, but what happens when the data size grows?  If we know the type of object we&#8217;re selecting, the query is straightforward and performs well:</p>
<pre name="code" class="sql">select
	 base_class.id
	,base_class.sub_type
	,inheriting_class.column1
..
	,inheriting_class.columnn
from
	base_class inner join inheriting_class on base_class.id = inheriting_class.base_class_id</pre>
<p>Using multiple tables, requires an inner join to select data and multiple updates to persist it. Outside high volume transaction applications, however, this cost this is negligible.<br />
The problem begins when we need to select a potentially heterogeneous set of records. The longer the inheritance chain and the larger number of sub-classes the less performant our queries will be.<br />
Suppose we have a relatively simple object model as follows:<br />
<a href="http://www.blogfor.net/wp-content/uploads/2008/05/TableClassInheritance.gif" ><img class="alignnone size-medium wp-image-33" title="image002" src="http://www.blogfor.net/wp-content/uploads/2008/05/image002-300x169.gif" alt="" /></a><br />
click the links for scripts to <a href="http://www.blogfor.net/wp-content/uploads/2008/05/createtables.sql"  target="_blank">create</a> and <a href="http://www.blogfor.net/wp-content/uploads/2008/05/populatetables.sql"  target="_blank">populate</a>.</p>
<p>In order to select a set of records &#8220;inheriting&#8221; from base_class, the business layer or OR/M will generate a query similar to the following (note I&#8217;m not selecting all the records, just a subset akin to the filters one would use in a real application):</p>
<pre name="code" class="sql">select
	 base_class.id
	,A.base_class_id
	,B.base_class_id
	,C.base_class_id
	,case when A.base_class_id is not null then 1 when B.base_class_id is not null then 2 when C.base_class_id is not null then 3 end as clazz_
from
	base_class left join inheriting_class_a as A on base_class.id = A.base_class_id
	left join inheriting_class_b as B on base_class.id = B.base_class_id
	left join inheriting_class_c as C on base_class.id = C.base_class_id
where base_class.id % 7 = 1</pre>
<p>On average the query takes 700ms on my machine (dual quad-core x64 xp). If we add in our knowledge of the sub-type into the join, the performance does not improve.</p>
<pre name="code" class="sql">select
	 base_class.id
	,A.base_class_id
	,B.base_class_id
	,C.base_class_id
	,case when A.base_class_id is not null then 1 when B.base_class_id is not null then 2 when C.base_class_id is not null then 3 end as clazz_
from
	base_class as base_class left join inheriting_class_a as A on base_class.id = A.base_class_id and base_class.sub_type = 2
	left join inheriting_class_b as B on base_class.id = B.base_class_id and base_class.sub_type = 0
	left join inheriting_class_c as C on base_class.id = C.base_class_id and base_class.sub_type = 1
where base_class.id % 7 = 1</pre>
<p>In fact the query execution plan is still the same despite a unique composite index on id and sub_type. The left joins are simply expensive. We need them to return heterogeneous results but the cost has become prohibitive. The longer the inheritance chain and the larger the number of sub-types, the more drastically the performance will degrade beyond this simple example.<br />
One workaround is to perform the expensive outer joins on a smaller subset of date. If we execute the same query using a <a href="http://msdn.microsoft.com/en-us/library/ms190766.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn.microsoft.com');">Common Table Expression</a> and filter the rows before doing the outer joins, the cost decreases by 50% to an average of 371ms.</p>
<pre name="code" class="sql">select
	 base_class.id
	,base_class.sub_type
	,C.base_class_id
	,B.base_class_id
	,C.base_class_id
	,case when A.base_class_id is not null then 1 when B.base_class_id is not null then 2 when C.base_class_id is not null then 3 end as clazz_
from
	base_class as base_class left join inheriting_class_a as C on base_class.id = C.base_class_id
	left join inheriting_class_b as B on base_class.id = B.base_class_id
	left join inheriting_class_c as C on base_class.id = C.base_class_id
where base_class.id % 7 = 1</pre>
<p>By comparison, using Single Table inheritance (click links for <a href="http://www.blogfor.net/wp-content/uploads/2008/05/createsingletableinheritance.sql" >create</a> and <a href="http://www.blogfor.net/wp-content/uploads/2008/05/populatesingletableinheritance.sql" >populate</a> scripts), the performace on the following:</p>
<pre name="code" class="sql">	select id, 1 as clazz_
	from sub_class_a
	where id %7 = 1
union all
	select id, 2 as clazz_
	from sub_class_b
	where id %7 = 1
union all
	select id, 3 as clazz_
	from sub_class_c
	where id %7 = 1</pre>
<p>is far better than that of the Class Table Inheritance at an average of 140ms. It&#8217;s important to note that performance will vary dramatically depending on the size of your data, the &#8220;selectiveness&#8221; of your where clause and other specifc circumstances.<br />
From the perspective of query performance, Single Table Inheritance is far more efficient than Class Table Inheritance. Within the context of Class Table Inheritance, what is not so obvious is that the cost of returning heterogenous lists or simply not knowing the sub-type at query time can be quite high.  Filtering the records (if possible) before applying the outer joins can drastically improve performance.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/05/27/class-table-inheritance-an-investigation-into-sql-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Howto: avoid binding the same eventhandler multiple times to an element event in the MS AJAX framework</title>
		<link>http://www.blogfor.net/2008/05/27/howto-avoid-binding-the-same-eventhandler-multiple-times-to-an-element-event-in-the-ms-ajax-framework/</link>
		<comments>http://www.blogfor.net/2008/05/27/howto-avoid-binding-the-same-eventhandler-multiple-times-to-an-element-event-in-the-ms-ajax-framework/#comments</comments>
		<pubDate>Tue, 27 May 2008 23:20:03 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=22</guid>
		<description><![CDATA[A workaround to duplicate event handler binding in Microsoft AJAX and a brief explanation how to avoid such problems in the first place.]]></description>
			<content:encoded><![CDATA[<p>The Microsoft AJAX <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Global/AddHandlerShortcutMethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">$addHandler</a> method is a wrapper to the browser specific implementations of the <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.w3.org');">w3c standard</a> e.g. $addHandler(element, eventName, handler).</p>
<p>Once you&#8217;ve bound an event handler to an element, there is no standard way to retrieve the binding information.  Javascript frameworks work around this limitation by setting custom properties on the html elements to track handler bindings.  As long as handlers are added and removed through the framework things will work as expected with one minor exception. If $addHandler is called twice with the same handler, when the event fires, <em>the handler fires twice</em>.</p>
<p>The Microsoft AJAX framework doesn&#8217;t check whether or not a delegate is already bound before binding it a second time, nor does it provide a means to determine what handlers are already bound. The best way to avoid this condition is by following the MS AJAX pattern for binding behaviors and elements. The pattern dictates that elements are &#8220;wrapped&#8221; in a one-to-one relationship with <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/ControlClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">controls</a>.  When a control is initialized it binds element events to its own internal delegates.  When other <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys.UI/BehaviorClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">behaviors</a> need to listen for events, they use the <a href="http://asp.net/AJAX/Documentation/Live/ClientReference/Sys/EventHandlerListClass/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/asp.net');">event handling architecture</a> for controls and behaviors by binding against the control, not the element.  Mike Ormond&#8217;s <a href="http://blogs.msdn.com/mikeormond/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">blog</a> provides a good <a href="http://blogs.msdn.com/mikeormond/archive/2008/03/25/building-asp-net-ajax-controls-pt-1.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');">explanation</a>.</p>
<p>Occasionally, you have the problem of adding the same handler multiple times. To work around this we need to know a little more about how the Microsoft framework tracks element event bindings.</p>
<p>When $addHandler is called, Microsoft AJAX adds an expando attribute to the element called &#8220;_events&#8221;. This is a hash table of the event bindings for the element. Element._events["eventName"] returns an array of delegates bound to the specified element event. The code below simply uses this internal implementation of the MS AJAX framework to avoid duplicate bindings. To use it, simply replace calls to $addHandler and $removeHandler with calls to $addHandlerIfNotDefined and $removeHandlerIfNotDefined.</p>
<pre name="code" class="javascript">$handlerDefined = function(elt, eventName, handler) {
	// returns true if an eventHandler has been defined for the given element and the given event
	if ( ( typeof( elt._events ) !== 'object' ) ||
		 ( elt._events === null ) ) {
		return false;
	}
	var cache = elt._events[eventName];
	if ( !(cache instanceof Array ) ) {
		return false;
	} else {
		for (var i=0, l = cache.length; i &lt; l; i+=1) {
				if (cache[i].handler === handler) {
					return true;
				}
		}
	}
}    

$addHandlerIfNotDefined = function(elt, eventName, handler) {
	// ensures the given handler is bound to the given element for the given event
	if ( !$handlerDefined( elt, eventName, handler ) ) {
		$addHandler(elt, eventName, handler);
	}
}    

$removeHandlerIfNotDefined = function(elt, eventName, handler) {
	// ensures the given handler is bound to the given element for the given event
	if ( $handlerDefined( elt, eventName, handler ) ) {
		$removeHandler(elt, eventName, handler);
	}
}</pre>
<p>Note: this solution does not handle new instances of anonymous delegates e.g.<br />
$addHandlerIfNotDefined(elt, &#8220;onclick&#8221;, new Function(evt){some code here});<br />
Since a new anonymous delegate is created each time the handler is added, we would need to compare both the &#8220;state&#8221; and &#8220;code of the delegate for instance equivalence. Determining delegate object equivalence is a difficult thing, the code above compares only delegate instance equivalence.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/05/27/howto-avoid-binding-the-same-eventhandler-multiple-times-to-an-element-event-in-the-ms-ajax-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Applying for technical jobs? A rough guide</title>
		<link>http://www.blogfor.net/2008/04/21/applying-for-technical-jobs-a-rough-guide/</link>
		<comments>http://www.blogfor.net/2008/04/21/applying-for-technical-jobs-a-rough-guide/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 01:58:09 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[general]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/2008/04/21/applying-for-technical-jobs-a-rough-guide/</guid>
		<description><![CDATA[Rough guideline to applying and interviewing for software development jobs. What to expect from process and common pitfalls.]]></description>
			<content:encoded><![CDATA[<p>For the last three years I&#8217;ve been involved in our company&#8217;s development team hiring process.  We&#8217;ve defined it, refined it, reworked it, and reworked it again.  We&#8217;ve made mistakes and made great hires.  I thought I&#8217;d share a few thoughts on the subject which you may find useful. </p>
<p>For every job posting online, we get 100+ applications.  For every diamond in the rough, there are many more applications we wish we didn&#8217;t spend time on.  We only want to hire great developers and have a rule: &#8220;no false positives&#8221;.  Although we may miss a &#8220;diamond in the rough&#8221; application, we try to make the time we spend hiring as effective as possible.  Usually we &#8220;ding&#8221; anyone who:</p>
<ol>
<li>Doesn&#8217;t have a cover letter.</li>
<li>Has numerous spelling errors on their resume or cover letter.</li>
<li>Submitted an application that takes us more than 30 seconds to determine what position you&#8217;re applying for and where you&#8217;re coming from (e.g. current job is &#8220;help desk&#8221;, but applying for a programmer position; went to school for art history).  For a better explanation check Rand In Repose&#8217;s <a href="http://www.randsinrepose.com/archives/2007/02/25/a_glimpse_and_a_hook.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.randsinrepose.com');">posting</a>.</li>
</ol>
<p>So how do you avoid these &#8220;dings&#8221;?</p>
<ol>
<li>Have someone proof read your resume</li>
<li>Check out other peoples resumes, e.g.  <a href="http://www.amazon.com/Resumes-That-KnockEm-Dead-Knock/dp/1580624227" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');" title="resumes that knock 'em dead">Resumes That Knock &#8216;Em Dead</a> and see formats that appear appropriate for the field you work in.</li>
<li>Use a cover letter customized to the position.  <a href="http://www.amazon.com/Cover-Letters-That-Knock-Dead/dp/1593377479/ref=pd_sim_b_img_2" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">Cover Letters That Knock &#8216;Em Dead</a> has a number of samples to get an idea of the tone and content of what your cover letter should contain.  Make sure to have someone proof read your cover letter before you apply.</li>
<li>Put things on your resume that HR people, recruiters, and automated systems can find.  I don&#8217;t mean highlight or boldface all your references to technologies (who started that trend anyways?), use certifications, associations, conferences, and trainings.  HR people aren&#8217;t developers.  They don&#8217;t know the difference between C# and VB.net or smalltalk and Ruby.  They know keywords they&#8217;ve been asked to look for, so make their job easier. By getting certifications, you may not be advancing your education so much as easing the first barrier to entry at any organization &#8211; survive the resume screening process.  Certs, conferences, and user groups indicate you&#8217;re serious about what you do for a career and advancing yourself professionally. HR people like this.</li>
</ol>
<p>You&#8217;ve submitted your cover letter and resume, and you get a call back.  The usual process is something like this:</p>
<ol>
<li>HR person/recruiter calls to qualify the application.  They want to sell you on the job &#8211; the company, the job itself, the benefits and also determine if this is a good fit for both parties.  They&#8217;ll ask the standard personnel questions and more specific questions they&#8217;re told to ask. for example
<ol>
<li>Why are you looking for a job?</li>
<li>When can you start?</li>
<li>What salary are you looking for?</li>
<li>What kind of job are you looking for?</li>
<li>What are your professional goals? -this one is very important. I can&#8217;t tell you how many people have applied for developer positions and told me &#8220;I want to get into business analysis/project management/developer management&#8221; &#8211; the job posting was specifically for a software engineer. Why did you apply?</li>
<li>Suppose you and someone have similar resumes. What makes you different?</li>
<li>What books have you read recently?</li>
<li>What blogs do you subscribe to?</li>
</ol>
<p>Be prepared for all of these.  The last three are really where we begin to distinguish ambition/character from professional qualifications. They&#8217;re good indicators (like education and certification) about what it is you want to do, how motivated you are, and a rough guide to your technical skills.</li>
<li>The technical phone screen.  This person is usually the hiring manager.  His goal is to further qualify you as a potential hire and to help sell you on the job with more details. Expect more technical questions and questions on your experience with certain technologies. </li>
<li>In person interview.</li>
</ol>
<p>Hopefully you made it through the screening process and are asked for a personal interview.   Get there early &#8211; &#8220;if you&#8217;re on time, you&#8217;re late&#8221;.  Once there, relax, use the bathroom, and review your information again- who the company is, what they do, the job description, and what information you&#8217;ve given them (resume, cover letter, references etc.).</p>
<p>Steve Yegge has a good description of the general onsite interview process and a whole lot more at &#8220;<a href="http://steve-yegge.blogspot.com/2008/03/get-that-job-at-google.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/steve-yegge.blogspot.com');">get that job at google</a>.&#8221; From his posting:</p>
<blockquote><p>Every &#8220;experienced&#8221; interviewer has a set of pet subjects and possibly specific questions that he or she feels is an accurate gauge of a candidate&#8217;s abilities. The question sets for any two interviewers can be widely different and even entirely non-overlapping.</p>
<p> A classic example found everywhere is: Interviewer A always asks about C++ trivia, filesystems, network protocols and discrete math. Interviewer B always asks about Java trivia, design patterns, unit testing, web frameworks, and software project management. For any given candidate with both A and B on the interview loop, A and B are likely to give very different votes. A and B would probably not even hire each other, given a chance, but they both happened to go through interviewer C, who asked them both about data structures, unix utilities, and processes versus threads, and A and B both happened to squeak by.</p>
<p> That&#8217;s almost always what happens when you get an offer from a tech company. You just happened to squeak by. Because of the inherently flawed nature of the interviewing process, it&#8217;s highly likely that someone on the loop will be unimpressed with you, even if you are Alan Turing. Especially if you&#8217;re Alan Turing, in fact, since it means you obviously don&#8217;t know C++.</p>
<p> The bottom line is, if you go to an interview at any software company, you should plan for the contingency that you might get genuinely unlucky, and wind up with one or more people from your Interview Anti-Loop on your interview loop. If this happens, you will struggle, then be told that you were not a fit at this time, and then you will feel bad. Just as long as you don&#8217;t feel meta-bad, everything is OK. You should feel good that you feel bad after this happens, because hey, it means you&#8217;re human.</p></blockquote>
<p>It helps to understand the perspective of the employer on the interview process. Joel Spolsky is an excellent resource on hiring developers.  His book entitled &#8220;<a href="http://www.amazon.com/Smart-Gets-Things-Done-Technical/dp/1590598385/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1208662110&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">Smart And Gets Things done</a>&#8220; and blog posting <a href="http://www.joelonsoftware.com/articles/GuerrillaInterviewing3.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.joelonsoftware.com');">The Guerrilla Guide to Interviewing</a> are essential resources for companies trying to find great talent. From his posting:</p>
<blockquote><p>You should always try to have at least six people interview each candidate that gets hired, including at least five who would be peers of that candidate (that is, other programmers, not managers). You know the kind of company that just has some salty old manager interview each candidate, and that decision is the only one that matters? These companies don’t have very good people working there. It’s too easy to fake out one interview, especially when a non-programmer interviews a programmer.<br />
 <br />
 If even two of the six interviewers thinks that a person is not worth hiring, don’t hire them. That means you can technically end the “day” of interviews after the first two if the candidate is not going to be hired, which is not a bad idea, but to avoid cruelty you may not want to tell the candidate in advance how many people will be interviewing them. I have heard of companies that allow any interviewer to reject a candidate. This strikes me as a little bit too aggressive; I would probably allow any senior person to reject a candidate but would not reject someone just because one junior person didn’t like them.</p>
<p>Look for passion. Smart people are passionate about the projects they work on. They get very excited talking about the subject. They talk quickly, and get animated. Being passionately negative can be just as good a sign. “My last boss wanted to do everything on VAX computers because it was all he understood. What a dope!” There are far too many people around that can work on something and not really care one way or the other. It’s hard to get people like this motivated about anything.</p>
<p>Bad candidates just don’t care and will not get enthusiastic at all during the interview. A really good sign that a candidate is passionate about something is that when they are talking about it, they will forget for a moment that they are in an interview.</p></blockquote>
<p>When interviewing we want to give the best impression possible. This is both easier and harder than it may seem.  According to Dave Munger in this <a href="http://scienceblogs.com/cognitivedaily/2006/05/the_sixsecond_teacher_evaluati.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/scienceblogs.com');">post</a> and Malcolm Gladwell in his book <a href="http://www.amazon.com/Blink-Power-Thinking-Without/dp/0316010669/ref=pd_bbs_sr_1?ie=UTF8&amp;s=books&amp;qid=1207198110&amp;sr=8-1" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.amazon.com');">Blink</a>(well worth reading), you&#8217;ll have about six seconds to make that first impression.  Presenting yourself with confidence and a humble smile will go a very long way to set the right tone for your interview.</p>
<p>Each individual interview will have several distinct sections.</p>
<ol>
<li>You&#8217;ll meet and shake hands.<br />
A recruiter once told me that at this moment, I should lean forward a little and stand on my toes.  He said it would make me stand up straighter and more importantly it would make me feel a little silly. This would in turn make me smile and relax. When I relaxed, the interviewer would relax.  After interviewing with 4 companies and 20 different people I will tell you, he was exactly right.  As the interviewer of 50+ people for two different companies, I can tell you the opposite is true- the candidates who don&#8217;t present themselves well usually have a harder interview as I try to draw them out.</li>
<li>The interviewer will tell you who they are and what they do. </li>
<li>They&#8217;ll ask you some questions. <br />
Be polite, be eager, and be positive during all of this. </li>
<li>Finally they&#8217;ll ask you if you have any questions.<br />
You should always have questions. Questions show you care about the position. It helps draw the interviewer into the conversation.  It&#8217;s also one of the only places during the interview process where you&#8217;ll get an idea what the job would actually be like.  Questions like: </p>
<ul>
<li>Who would I be working with? (Are they of your caliber? Are they as motivated as you are?)</li>
<li>What would be the first project/team I&#8217;d work on here?</li>
<li>What would I need to do to meet or exceed expectations after 6 months? (OK this one is a little cheesy, but sometimes effective)</li>
<li>Who would be my manager?</li>
<li>What feedback loop do you have for my performance?</li>
<li>What is the primary focus of the position (you may get a different answer depending on who you ask) &#8211; technical? interfacing with users? project management?</li>
</ul>
</li>
</ol>
<p>So you&#8217;re interview is done, and you&#8217;re on your way out.  Don&#8217;t forget to thank everyone you met, including their &#8220;staff&#8221;.  Take a moment when you finally get out of there and write down some notes of your impressions (you&#8217;ll forget things by the time you get home) what people said, the specifics of the actual job, etc. </p>
<p>A few final notes:</p>
<ul>
<li>2 weeks notice to your current employer is standard &#8211; if they expect you to leave without notice, it says something about how much they care about people.</li>
<li>Always get time to think about the offer- &#8220;I have to speak with my family&#8221; is a valid answer.  Anyone who goes for the hard sell is sketchy.</li>
<li>If things don&#8217;t pan out, it&#8217;s probably because someone (and it only takes one) thought you weren&#8217;t the best fit.  That may be true, it may not, but better no fit than a bad one. </li>
<li>Big companies can afford a longer ramp up time and better training.  Smaller ones are generally looking for you to hit the ground running.  Don&#8217;t be upset if someone thought you&#8217;d require a little too much training to be useful to them- it&#8217;s them, not you :)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/21/applying-for-technical-jobs-a-rough-guide/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YSlow and ASP.NET &#8211; Expires Header &#8211; BuildProvider (Part 3 of 3)</title>
		<link>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-buildprovider-part-3-of-3/</link>
		<comments>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-buildprovider-part-3-of-3/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 01:02:20 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-buildprovider-part-3-of-3/</guid>
		<description><![CDATA[How to use a buildProvider to provide codebehind based support for dynamic location of static content.  Part three of three in series to utilize static content versioning to reduce http request through extended content caching.]]></description>
			<content:encoded><![CDATA[<p>For the last part of our quest to enable caching of static content by separating it out into directories by version, we want to provide an easy and intuitive way for developers to reference static content from the code behind. e.g.</p>
<pre name="code" class="vb.net">
Dim linkIcon As New System.Web.UI.WebControls.Image
linkIcon.ImageUrl = StaticContent.Images.rss_gif</pre>
<p>Under the covers StaticContent.Images.rss_gif resolves to a method call -StaticContent.PathBuilder.ConvertImageUrl(&#8221;rss.gif&#8221;) (the method is covered in part 2).<br />
To do this we need a <a href="http://msdn2.microsoft.com/en-us/library/system.web.compilation.buildprovider.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">buildProvider</a> (Note: this is not supported in Web Application Projects (WAP) see notes at the end).<br />
The code is mostly written for us on <a href="http://www.singular.co.nz/blog/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.singular.co.nz');">Dave Transom&#8217;s </a>excellent <a href="http://www.singular.co.nz/blog/archive/2008/02/03/build-providers-and-strongly-typed-page-urls-in-asp-net.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.singular.co.nz');">post</a>.<br />
The slightly modified code is <a href="http://www.blogfor.net/wp-content/uploads/2008/04/buildprovider.vb"  title="BuildProvider.vb">here</a>.<br />
Now that we have a buildProvider we wire it into the build using the web.config:</p>
<pre name="code" class="xml">
&lt;compilation debug="true" strict="true" explicit="true"&gt;
	&lt;buildProviders&gt;
		&lt;add extension=".hrefs" type="Savo.Framework.Web.StaticContent.BuildProvider"/&gt;
	&lt;/buildProviders&gt;
&lt;/compilation&gt;</pre>
<p>To configure our BuildProvider create a file with the extension &#8220;.hrefs&#8221; in your App_Code directory, using some variation on the following:</p>
<pre name="code" class="xml">
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;settings
	namespace=""
	className="StaticContent"
	minDepth="1"
	maxDepth="100"
	lowercaseUrls="true"
	includeExtension="true"
	truncatePathToStartingDepth="true"
	resourceResolutionFormat='StaticContent.PathBuilder.ConvertStaticContentUrl("{0}")'
	directoryNamesToIgnore="StaticContent"&gt;
	&lt;files include="\.(gif|jpg|png|css)$" exclude=""&gt;
	&lt;folders include="StaticContent" exclude="App_|Bin|\.svn"&gt;
&lt;/settings&gt;</pre>
<p>If you&#8217;re using a &#8220;Web Application Project&#8221;, this method won&#8217;t work as per this <a href="http://msdn2.microsoft.com/en-us/library/aa983464.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">MS post</a>.  My suggestion is to use a <a href="http://msdn2.microsoft.com/en-us/library/e2s2128d(VS.80).aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">pre-build event</a> (although this has a few extra gotchas) or another framework like <a href="http://bchavez.bitarmory.com/archive/2007/09/03/slink-framework---strongly-typed-urls-for-asp.net.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/bchavez.bitarmory.com');">slink</a> though I haven&#8217;t tried either method.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-buildprovider-part-3-of-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YSlow and ASP.NET &#8211; Expires Header &#8211; Expression Builders (Part 2 of 3)</title>
		<link>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-expression-builders-part-2-of-3/</link>
		<comments>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-expression-builders-part-2-of-3/#comments</comments>
		<pubDate>Tue, 22 Apr 2008 00:43:00 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-expression-builders-part-2-of-3/</guid>
		<description><![CDATA[How to use expressionBuilders to provide markup based support for dynamic location of static content.  Part two of three in series to utilize static content versioning to reduce http request through extended content caching.]]></description>
			<content:encoded><![CDATA[<p>Continuing our task of caching indefinitely static content by versioning it, we want to build the framework so that instead of code like this:</p>
<pre name="code" class="xml">
&lt;asp:image imageurl="~/images/rose.jpg" runat="server" id="image1"&gt;</pre>
<p>we have this:</p>
<pre name="code" class="xml">
&lt;asp:Image id="image1" imageurl="&lt;%$ Image: rose.jpg %&gt;" runat="server"/&gt;</pre>
<p>The key difference is that we can dynamically assign where the image path for rose.jpg resolves in the latter case. Specifically, we can resolve to applicationPath/versionX.X.X/Images/rose.jpg (or whatever url scheme meets your fancy).</p>
<p>We need two things. First we create an expressionBuilder object and then tie the custom expressionBuilder into the build. I&#8217;m using the VS &#8220;WebSite&#8221; project, but this should work for &#8220;Web Application Projects&#8221;.</p>
<p>The following code draws heavily from this <a href="http://weblogs.asp.net/infinitiesloop/archive/2006/08/09/The-CodeExpressionBuilder.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">post</a> on Dave Reed&#8217;s excellent blog <a href="http://weblogs.asp.net/infinitiesloop/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">infinitiesloop</a>.</p>
<pre name="code" class="vb.net">
Imports System.CodeDom
Imports System.Web         

Namespace StaticContent         

	Public NotInheritable Class PathBuilder         

		Private Shared CssPath As String = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}/StaticContent/{1}/Css/{{0}}", System.Web.HttpContext.Current.Request.ApplicationPath, System.Configuration.ConfigurationManager.AppSettings("versionNumber")))
		Private Shared ImagePath As String = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}/StaticContent/{1}/Images/{{0}}", System.Web.HttpContext.Current.Request.ApplicationPath, System.Configuration.ConfigurationManager.AppSettings("versionNumber")))
		Private Shared JavascriptPath As String = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0}/StaticContent/{1}/Javascripts/{{0}}", System.Web.HttpContext.Current.Request.ApplicationPath, System.Configuration.ConfigurationManager.AppSettings("versionNumber")))         

		Public Shared Function ConvertCssUrl(ByVal path As String) As String
			Return String.Format(System.Globalization.CultureInfo.InvariantCulture, CssPath, path)
		End Function         

		Public Shared Function ConvertImageUrl(ByVal path As String) As String
			Return String.Format(System.Globalization.CultureInfo.InvariantCulture, ImagePath, path)
		End Function         

		Public Shared Function ConvertJavascriptUrl(ByVal path As String) As String
			Return String.Format(System.Globalization.CultureInfo.InvariantCulture, JavascriptPath, path)
		End Function         

		Private Sub New()
		End Sub         

	End Class         

	MustInherit Class StaticContentExpressionBuilder
		Inherits Compilation.ExpressionBuilder         

		Protected Shared evaluationExpression As String         

		Protected MustOverride ReadOnly Property StaticContentExpression() As String         

		Public Overrides Function ParseExpression(ByVal expression As String, ByVal propertyType As System.Type, ByVal context As Compilation.ExpressionBuilderContext) As Object
			Return String.Format(System.Globalization.CultureInfo.InvariantCulture, StaticContentExpression, expression)
		End Function         

		Public Overloads Overrides Function GetCodeExpression(ByVal entry As System.Web.UI.BoundPropertyEntry, ByVal parsedData As Object, ByVal context As System.Web.Compilation.ExpressionBuilderContext) As System.CodeDom.CodeExpression
			Return New CodeSnippetExpression(parsedData.ToString())
		End Function         

	End Class         

	&lt;Compilation.ExpressionPrefix("Js")&gt; _
 Class JavascriptExpressionBuilder
		Inherits StaticContentExpressionBuilder         

		Protected Overrides ReadOnly Property StaticContentExpression() As String
			Get
				Return "StaticContent.PathBuilder.ConvertJavascriptUrl( ""{0}"" )"
			End Get
		End Property         

	End Class         

	&lt;Compilation.ExpressionPrefix("Image")&gt; _
	Class ImageExpressionBuilder
		Inherits StaticContentExpressionBuilder         

		Protected Overrides ReadOnly Property StaticContentExpression() As String
			Get
				Return "StaticContent.PathBuilder.ConvertImageUrl( ""{0}"" )"
			End Get
		End Property         

	End Class         

	&lt;Compilation.ExpressionPrefix("Css")&gt; _
	Class CssExpressionBuilder
		Inherits StaticContentExpressionBuilder         

		Protected Overrides ReadOnly Property StaticContentExpression() As String
			Get
				Return "StaticContent.PathBuilder.ConvertCssUrl( ""{0}"" )"
			End Get
		End Property         

	End Class         

End Namespace</pre>
<p>I&#8217;ve chosen to implement several types of static content (css, images, and js) but that&#8217;s just a matter of convenience. Clearly this could all be done with a single expression. Note the reason I have placed the content type specific methods on PathBuilder is that I need to call these methods in part three (code-behind) where accessing the expressionBuilder assemblies would be pretty awkward.</p>
<p>To tie our new expression builders into the build we need to add some entries to the web.config.</p>
<pre name="code" class="xml">
&lt;compilation debug="true" strict="true" explicit="true"&gt;
	&lt;expressionBuilders&gt;
		&lt;add expressionPrefix="Css" type="StaticContent.CssExpressionBuilder"/&gt;
		&lt;add expressionPrefix="Image" type="StaticContent.ImageExpressionBuilder"/&gt;
		&lt;add expressionPrefix="Js" type="StaticContent.JavascriptExpressionBuilder"/&gt;
	&lt;/expressionBuilders&gt;
&lt;/compilation&gt;</pre>
<p>That&#8217;s it. Now we can do things in our markup like:</p>
<pre name="code" class="xml">
&lt;asp:image imageurl="Image: rose.jpg" runat="server" id="image1"&gt;
&lt;link rel="stylesheet" href="Css: Fonts.css %&gt;" type="text/css" id="FontsCss" runat="server"&gt;</pre>
<p>the image &#8220;rose.jpg&#8221; and css file &#8220;Fonts.css&#8221; will be rendered to the page as urls:<br />
&#8220;applicationPath/StaticContent/1.0.0/Images/rose.jpg&#8221; and &#8220;applicationPath/StaticContent/1.0.0/Css/Fonts.css&#8221; respectively.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/21/yslow-and-aspnet-expires-header-expression-builders-part-2-of-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>YSlow and ASP.NET &#8211; Concatenating and Minifying Css and Js Resources</title>
		<link>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-concatenating-and-minifying-css-and-js-resources/</link>
		<comments>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-concatenating-and-minifying-css-and-js-resources/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 04:30:38 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[nant]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=17</guid>
		<description><![CDATA[Example of using Nant and YUICompressor to concatenate and minify js and css resources through the automated build to reduce download size and http request count]]></description>
			<content:encoded><![CDATA[<p>In our code we reference several js libraries (prototype, scriptaculous, custom libraries etc.) and we break our css out into several files (layout, fonts, etc.). We encouraged our developers to use whitespace, comments, descriptive names, and separate files to make code as clear as possible. Clear code, however, results in longer download times for web clients.  We wanted to follow the suggestions from the <a href="http://yuiblog.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/yuiblog.com');">YUI</a> folks to <a href="http://developer.yahoo.com/performance/rules.html#minify" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">minify</a> and <a href="http://developer.yahoo.com/performance/rules.html#num_http" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">concatenate</a> our resources so that clear code and fast download times could co-exist.</p>
<p>The answer was our automated build. It would have the job of minifying the js and css. It would concatenate the resources together into two files &#8211; one for js and one for css.</p>
<p>To use concatenated resources in our code while preserving the ability of developers we work, we changed the the markup section of our master slightly to:</p>
<pre name="code" class="html">
&lt;head runat="server"&gt;
	&lt;!-- css --&gt;
	&lt;!--	PLEASE NOTE: CSS and JS ARE COMBINED ON AUTOMATED BUILD
				Please add entries there as necessary!!
	--&gt;
	&lt;link rel="stylesheet" href="Css/Fonts.css" type="text/css" id="FontsCss" runat="server"&gt;
	&lt;link rel="stylesheet" href="Css/Structure.css" type="text/css" id="StructureCss" runat="server"&gt;
	&lt;link rel="stylesheet" href="Css/Hyperlinks.css;" type="text/css" id="HyperlinksCss" runat="server"&gt;
	&lt;link rel="stylesheet" href="Css/Menus.css" type="text/css" id="MenusCss" runat="server"&gt;
	&lt;link rel="stylesheet" href="Css/Concatenated.css;" type="text/css" id="ConcatenatedCss" runat="server" visible="false"&gt;
	&lt;!-- javascript --&gt;
	&lt;ScriptReference:ScriptRef src="Js/prototype.js" runat="server" ID="UiPrototypeJs"&gt;
	&lt;!-- note there are multiple files downloaded after scriptaculous loads, these files should already be included in the concatenated.js if appropriate--&gt;
	&lt;ScriptReference:ScriptRef src="Js/library/scriptaculous.js" runat="server" ID="ScriptaculousJs"&gt;
	&lt;ScriptReference:ScriptRef src="Js/library/application.js" runat="server" ID="ApplicationJs"&gt;
	&lt;ScriptReference:ScriptRef src="Js/library/Concatenated.js;" runat="server" ID="ConcatenatedScript" Visible="false"&gt;
&lt;/head&gt;</pre>
<p>Note: asp.net doesn&#8217;t have a server control for script elements, so we roll our own server control:</p>
<pre name="code" class="vb.net">
Imports System
Imports System.Web.UI       

	Public Class ScriptRef
		Inherits WebControls.Literal       

		Private Const _scriptRefMarkup As String = "&lt;script src="" mce_src=""{0}"" type=""text/javascript""&gt;&lt;/script&gt;"       

		Public Property Src() As String
			Get
				Return Me.Text
			End Get
			Set(ByVal value As String)
				If Not value Is Nothing Then
					Me.Text = String.Format(Globalization.CultureInfo.InvariantCulture, _scriptRefMarkup, value.Replace("~", System.Web.HttpContext.Current.Request.ApplicationPath))
				End If
			End Set
		End Property       

	End Class</pre>
<p>At runtime we can now choose whether to show the css/js files or our concatenated version:</p>
<pre name="code" class="vb.net">
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
	MyBase.OnInit(e)       

	Dim useConcatenatedJsAndCss As Boolean = False
	If Not String.IsNullOrEmpty(System.Configuration.ConfigurationManager.AppSettings("useConcatenatedJsAndCss")) AndAlso System.Boolean.TryParse(System.Configuration.ConfigurationManager.AppSettings("useConcatenatedJsAndCss"), useConcatenatedJsAndCss) AndAlso useConcatenatedJsAndCss Then
		If useConcatenatedJsAndCss Then
			'NOTE: Whatever we set to visible false here has to be added to the
			'build to be included in the Concatenated css
			FontsCss.Visible = False
			StructureCss.Visible = False
			HyperlinksCss.Visible = False
			MenuCss.Visible = False       

			PrototypeJs.Visible = False
			ScriptaculousJs.Visible = False
			ApplicationJs.Visible = False       

			UiConcatenatedCss.Visible = True
			UiConcatenatedScript.Visible = True
		End If
	End If
End Sub</pre>
<p>using the config setting &#8220;useConcatenatedJsAndCss&#8221;</p>
<pre name="code" class="html">
	&lt;appSettings&gt;
		&lt;add key="useConcatenatedJsAndCss" value="false"/&gt;
	&lt;/appSettings&gt;</pre>
<p>For minification, we used the <a href="http://www.julienlecomte.net/yuicompressor/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.julienlecomte.net');">YUICompressor</a>. Download it to a place where the build can find it.</p>
<pre name="code" class="html">
&lt;target name="CleanCss"&gt;
	&lt;foreach item="File" in="${PathToYourWebSiteBuildOutput}/Css" property="filename"&gt;
		&lt;property name="extension" value="${path::get-extension(filename)}"&gt;
		&lt;property name="extension2" value="${string::to-lower(extension)}"&gt;
		&lt;property name="isCss" value="${string::ends-with(extension2, 'css')}"&gt;
		&lt;if test="${isCss}"&gt;
			&lt;exec program="java"&gt;
				&lt;arg value="-jar"&gt;
				&lt;arg value="${YUICompressorPath}"&gt;
				&lt;arg value="-o"&gt;
				&lt;arg value="${filename}.min"&gt;
				&lt;arg value="${filename}"&gt;
				&lt;arg value="--warn"&gt;
				&lt;arg value="--charset"&gt;
				&lt;arg value="Cp1252"&gt;
			&lt;/exec&gt;
			&lt;move file="${filename}.min" tofile="${filename}" overwrite="true"&gt;
		&lt;/if&gt;
	&lt;/foreach&gt;
&lt;/target&gt;       

&lt;target name="CleanJs"&gt;
	&lt;foreach item="File" property="filename"&gt;
		&lt;in&gt;
			&lt;items&gt;
				&lt;include name="${PathToYourWebSiteBuildOutput}/Javascripts/**/*.js"&gt;
			&lt;/items&gt;
		&lt;/in&gt;
		&lt;do&gt;
			&lt;property name="extension" value="${path::get-extension(filename)}"&gt;
			&lt;property name="extension2" value="${string::to-lower(extension)}"&gt;
			&lt;property name="isJs" value="${string::ends-with(extension2,'js')}"&gt;
			&lt;if test="${isJs}"&gt;
				&lt;exec program="java"&gt;
					&lt;arg value="-jar"&gt;
					&lt;arg value="${YUICompressorPath}"&gt;
					&lt;arg value="-o"&gt;
					&lt;arg value="${filename}.min"&gt;
					&lt;arg value="${filename}"&gt;
					&lt;arg value="--preserve-semi"&gt;
					&lt;arg value="--charset"&gt;
					&lt;arg value="Cp1252"&gt;
				&lt;/exec&gt;
				&lt;move file="${filename}.min" tofile="${filename}" overwrite="true"&gt;
			&lt;/if&gt;
		&lt;/do&gt;
	&lt;/foreach&gt;
&lt;/target&gt;</pre>
<p>Note: when calling jsmin from the commandline we need to specify the character set for the file we&#8217;re compressing or use the default format (ANSI).</p>
<p>For concatenation we can use the build task &#8220;concat&#8221;. When concatenating files, order is important so we enumerate the files explicitly:</p>
<pre name="code" class="xml">
&lt;target name="CombineCss"&gt;
	&lt;!-- ordering of concat filesets is nondeterministic, so we concat separately --&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Css\Concatenated.css" append="false"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Css/Fonts.css"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Css\Concatenated.css" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Css/structure.css"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Css\Concatenated.css" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Css/Hyperlinks.css"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Css\Concatenated.css" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Css/Menus.css"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
&lt;/target&gt;     

&lt;target name="CombineJs"&gt;
	&lt;!-- ordering of concat filesets is nondeterministic, so we concat separately --&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/prototype.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/scriptaculous.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/crir.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/builder.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/effects.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/dragdrop.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/controls.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
	&lt;concat destfile="${WebSiteStaticContentVersionDirectoryPath}\Javascripts\library\Concatenated.js" append="true"&gt;
		&lt;fileset&gt;
			&lt;include name="${WebSiteStaticContentVersionDirectoryPath}/Javascripts/library/slider.js"&gt;
		&lt;/fileset&gt;
	&lt;/concat&gt;
&lt;/target&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-concatenating-and-minifying-css-and-js-resources/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>YSlow and ASP.NET &#8211; Expires Header (Part 1 of 3)</title>
		<link>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-expires-header-part-1-of-3/</link>
		<comments>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-expires-header-part-1-of-3/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 03:51:03 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=16</guid>
		<description><![CDATA[Overview of solution to versioning static content in asp.net so that it can be cached indefinitely by the browser.]]></description>
			<content:encoded><![CDATA[<p>At our company there&#8217;s a focus on getting our asp.net web application to perform in IE6/7 and FF.  Our site uses javascript and css heavily which results in less than optimal performance.  In an effort to improve performance we took proactive steps by:</p>
<ul>
<li>the size of viewstate and http response on all asp.net requests</li>
<li>logging the number of queries used on each http request</li>
<li>using the excellent tool <a href="http://developer.yahoo.com/yslow/" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">YSlow </a>to get insight into the actual content rendered</li>
</ul>
<p>In future posts I plan to touch upon changes we made in response to these results including <a href="http://developer.yahoo.com/performance/rules.html#minify" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">minimizing</a> our javascript and css files with <a href="http://developer.yahoo.com/yui/compressor/" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">YUICompressor</a> and concatenating the results to reduce the <a href="http://developer.yahoo.com/performance/rules.html#num_http" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">number of http requests</a> through our continuous integration process.</p>
<p>The specific challenge I hope to illustrate concerns the default asp.net http headers for <a href="http://developer.yahoo.com/performance/rules.html#expires" onclick="javascript:pageTracker._trackPageview('/outbound/article/developer.yahoo.com');">content expiration</a>.  By default, asp.net and IIS serve resources with &#8220;Cache-Control: private&#8221;.  When you close your browser (or the current tab) the content may be cached (depending on your browser (FF and IE6/7 each handle this differently). When the user returns to your site he will either re-request the file and receive an HTTP 304 (&#8221;not modified since&#8221;) response or download the entire file again. </p>
<p>In the case where your site has lots of images, js, or css files, you can end up issuing a lot of needless http requests for recurring users.  If instead you were able to set the http cache header to something in the far future, then the browser wouldn&#8217;t request the file in the first place.  Scott Hanselman has a good discussion of this behavior <a href="http://www.hanselman.com/blog/ForcingAnUpdateOfACachedJavaScriptFileInIIS.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hanselman.com');">here</a>.</p>
<p>In order to cache items at the client you need a way to version them e.g. &#8220;~/images/logo.jpg&#8221; becomes &#8220;v1.0.0/images/logo.jpg&#8221;. This way when the resources change they have new paths. These new paths are served up in your markup- the img.src attribute is now different than anything in cache and the browser must therefore request the new version (whose expiration header is also set to a far future date).</p>
<p>The catch is that while asp.net uses the ResolveUrl method and natively changes &#8220;~/images/logo.jpg&#8221; to &#8220;/myapplication/images/logo.jpg&#8221;, there is no such mechanism built into the framework to make it translate &#8220;~/images/logo.jpg&#8221; to &#8220;/myapplication/v1.0.0/images/logo.jpg&#8221;.</p>
<p>This is a fun problem to solve. It has two parts.</p>
<p>First we must create a framework so that static content can be served easily from the markup by substituting &#8220;~/images/logo.jpg&#8221; for &#8220;&lt;%$ Images: logo.jpg %&gt;&#8221;. </p>
<p>Part 2 will be addressed using <a href="http://msdn2.microsoft.com/en-us/library/system.web.compilation.expressionbuilder.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">expressionBuilders</a>  </p>
<p>Secondly we need to create the framework so that in the code behind, we can replace img.url = &#8220;~/images/logo.jpg&#8221; with img.url = StaticContent.images.logo_jpg.</p>
<p>Part 3 will be addressed using a <a href="http://msdn2.microsoft.com/en-us/library/h0e51sw9.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">build provider</a>.</p>
<p>Both parts will require changes to our build process not covered here.  The continuous integration process should include in its build archive a directory of the static content named by the version number (e.g. v1.0.0) and updating a application configuration property with the specific version so that the application can reference the static content directory properly. </p>
<p>The Continuous Integration changes will not be covered here because they are very specific to one&#8217;s own continuous integration process.  We currently use <a href="http://nant.sourceforge.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/nant.sourceforge.net');">nant</a> with <a href="http://xmlpreprocess.sourceforge.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/xmlpreprocess.sourceforge.net');">xmlPreprocess</a> to generate our configuration files for each version and environment (prod, dev, qa, etc.), but there are a ton of ways to do this, all outside of asp.net. Using a small ruby script we generate an additional master settings file to incorporate the latest version number in the master configuration.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/20/yslow-and-aspnet-expires-header-part-1-of-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I wish I knew about Service Broker before I started using it</title>
		<link>http://www.blogfor.net/2008/04/20/what-i-wish-i-knew-about-service-broker-before-i-started-using-it/</link>
		<comments>http://www.blogfor.net/2008/04/20/what-i-wish-i-knew-about-service-broker-before-i-started-using-it/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 03:28:42 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=14</guid>
		<description><![CDATA[Quick hitlist of things we've learned about MS Service Broker that one might not realize at first.]]></description>
			<content:encoded><![CDATA[<p>My current work involves asyncronous communication between multiple servers. Servers in the web farm submit jobs for processing by various backend server farms. Over time our implementation evolved from a simple stored procedure call that polled a table to a much more scalable and fault tolerant MSMQ implementation.</p>
<p>We moved to MSMQ because polling SQL Server tables leads to locking issues with multiple pollers and larger data sets.  Unfortunately, the move to MSMQ separated messages from data, requiring complicated logic to simulate distrubuted transactions across queues and the database. We moved to SQL Service Broker because it is designed to handle multiple pollers, utilizes t-sql,and calls are made inside the current t-sql transaction.</p>
<p>Unfortunately the documentation for Service Broker isn&#8217;t all that intuitive and the Microsoft tools (Sql Management Studio in particular) don&#8217;t really make things easier. Learning about Service Broker takes time and a healthy dose of experimentation.  Our implementation has been live now for several months and is working well.</p>
<p>Here are a few things we learned along the way:</p>
<ul>
<li>you can see what messages are in a queue by selecting from it &#8211; select * from myQueue.</li>
<li>the system views <a href="http://msdn2.microsoft.com/en-us/library/ms187795.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">sys.service_queues</a> and <a href="http://msdn2.microsoft.com/en-us/library/ms190336.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');">sys.transmission_queue</a> are your friends. If messages are sent but don&#8217;t show up in the queue, check the reason column of the transmission queue.  Most of the time it is because the database master key permissions aren&#8217;t set correctly, particularly if the database has been restored. </li>
<li>permissions need to be granted on queues and services to send and receive from them:
<pre name="code" class="sql">
--Grant the user access to the service
GRANT SEND ON SERVICE::[Your_Service_Name] TO [domain\john.doe] ;
--Grant the user send rights
GRANT RECEIVE ON [Your_Queue_Name] TO [domain\john.doe] ;
--Grant the user receive rights
GRANT SEND ON [Your_Queue_Name] TO [domain\john.doe] ;</pre>
</li>
<li>when using Activation on queues the procedure actions are included in the current transaction/</li>
<li>sending/receiving messages are included in the current transaction.</li>
<li>sql management studio does not script broker objects &#8220;naturally&#8221; &#8211; when you script database objects through the UI, service broker objects aren&#8217;t included. When you script service broker objects, permissions aren&#8217;t included</li>
<li>
<pre name="code" class="sql">
Alter database your_database set new_broker</pre>
<p>will clear all your queues</li>
<li>messages in queues are encrypted by default. All messages are hex encoded.</li>
<li>if you use a common data store for each endpoint, keep messages as terse as possible. The actual content of the messages is less important than the message itself. If you need additional data, you can retrieve it from the database.</li>
</ul>
<p>Service Broker has more features than any standard user is likely to encounter.  Asyncronous symptoms can be complicated; building a secure, scalable, fault tolerant system takes a lot of forethought.  Until Microsoft better integrates its product we have blogs, technical articles, forums, etc. to help augment the existing information. Good luck.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/20/what-i-wish-i-knew-about-service-broker-before-i-started-using-it/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>T-SQL Split &#8211; An xml based approach</title>
		<link>http://www.blogfor.net/2008/04/20/t-sql-split-an-xml-based-approach/</link>
		<comments>http://www.blogfor.net/2008/04/20/t-sql-split-an-xml-based-approach/#comments</comments>
		<pubDate>Mon, 21 Apr 2008 02:38:42 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=9</guid>
		<description><![CDATA[User defined function for splitting lists of integers with optimization for lists of unique items.]]></description>
			<content:encoded><![CDATA[<p>When we select information from our database we have to be careful to filter only results that the user has access to, e.g. an user has access to user information in a fixed list of departments:</p>
<pre name="code" class="sql">
Select * from Employee where department_id in (1,3,6)</pre>
<p>The problem is comes when we try to parameterize our query because T-SQL requires a parameter for each item in the &#8220;IN&#8221; clause.  When we use our OR/M (nHibernate) and the setParameterList method, it creates a query like this:</p>
<pre name="code" class="sql">
sp_executeSql(n'Select * from Employee where department_id in (@p0,@p1,@p2)',
'@p0 int, @p1 int, @p2 int',
@p0=1,@p1=3,@p2=6);</pre>
<p>This has a few issues:</p>
<ol>
<li>As the list size increases, query performance degrades due to the number of parameters.</li>
<li>We risk throwing a &#8220;Too many parameters were provided in this RPC request. The maximum is 2100&#8243; error depending on the number of items in the list(s) the query uses.</li>
<li>These queries cannot be cached effectively because of the variations in parameters.</li>
</ol>
<p>We considered building a list of comma delimited ids, passing that to SQL as an nvarchar parameter, and using a user defined function like this:</p>
<pre name="code" class="sql">
Select * from SomeTable where id in (dbo.fnSplit(@ids))</pre>
<p>After some investigation, however, we found no standard way to implement the fnSplit function. Everybody has their own version optimized for list size, ordering, and format.</p>
<p>Instead we serialized the list to xml (pretty easy in.net) and deserialized it using:</p>
<pre name="code" class="sql">
CREATE FUNCTION [dbo].[fn_SplitIntsFromXmlNoPrimaryKey](@input varchar(max))
RETURNS @retArray TABLE (id int)
AS
BEGIN
	DECLARE @xml xml
	SET @xml = @input
	insert into @retArray
	SELECT   T.id.value('.', 'int') AS id
	FROM @xml.nodes('/ArrayOfInt/int') T(id)
	RETURN
END</pre>
<pre name="code" class="sql">
select * from [dbo].[fn_SplitIntsFromXmlNoPrimaryKey] (
'<arrayofint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"></arrayofint>
  <int></int>33
  <int></int>72
  <int></int>74
  <int></int>76
  <int></int>78
  <int></int>80
<int></int>80
 ')</pre>
<p>For larger numbers of ids, performance degraded due to the table scan:<br />
<img src="http://www.blogfor.net/wp-content/uploads/2008/03/fnsplitwithnoprimarykey.JPG" alt="fnSplitWithNoPrimaryKey" /><br />
So we optimized the function by introducing a primary key on the ints:</p>
<pre name="code" class="sql">
CREATE FUNCTION [dbo].[fn_SplitIntsFromXml](@input varchar(max))
RETURNS @retArray TABLE (id int Primary Key)
AS
BEGIN
	DECLARE @xml xml
	SET @xml = @input
	insert into @retArray
	SELECT   T.id.value('.', 'int') AS id
	FROM @xml.nodes('/ArrayOfInt/int') T(id)
	RETURN
END</pre>
<pre name="code" class="sql">
select * from [dbo].[fn_SplitIntsFromXml] (
'<arrayofint xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"></arrayofint>
  <int></int>33
  <int></int>72
  <int></int>74
  <int></int>76
  <int></int>78
  <int></int>80
 ')</pre>
<p><img src="http://www.blogfor.net/wp-content/uploads/2008/03/fnsplitwithprimarykey.JPG" alt="fnSplitWithPrimaryKey" /><br />
For several thousand ids, the performance difference was quite dramatic at 1 second versus 13 seconds. Although our testing was light it was conclusive- a primary key allows SQL to avoid using a heap for storing/searching the table valued function result and this is much faster. Since we&#8217;re using a single parameter per IN clause, we are no longer limited by the RPC parameter limit, the query plan can be cached, and performance is within limits.<br />
Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/20/t-sql-split-an-xml-based-approach/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Concatenating values in t-sql select statements</title>
		<link>http://www.blogfor.net/2008/04/19/concatenating-values-in-t-sql-select-statements/</link>
		<comments>http://www.blogfor.net/2008/04/19/concatenating-values-in-t-sql-select-statements/#comments</comments>
		<pubDate>Sun, 20 Apr 2008 00:05:44 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[t-sql]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=8</guid>
		<description><![CDATA[How to concatenate values within select statements]]></description>
			<content:encoded><![CDATA[<p>In a previous life, I worked on purchasing software.  One of the performance problems that continually plagued us stemmed from a fundamental decision we made about how we tracked the line items of an order:</p>
<table style="width: 281px; height: 94px">
<tr>
<td>
<p align="center">orderLineId</p>
</td>
<td>
<p align="center">orderId</p>
</td>
<td>
<p align="center">qty</p>
</td>
<td>
<p align="center">product</p>
</td>
</tr>
<tr>
<td>
<p align="center">1</p>
</td>
<td>
<p align="center">123</p>
</td>
<td>
<p align="center">1</p>
</td>
<td>
<p align="center">Product A</p>
</td>
</tr>
<tr>
<td>
<p align="center">2</p>
</td>
<td>
<p align="center">123</p>
</td>
<td>
<p align="center">1</p>
</td>
<td>
<p align="center">Product A</p>
</td>
</tr>
<tr>
<td>
<p align="center">3</p>
</td>
<td>
<p align="center">123</p>
</td>
<td>
<p align="center">1</p>
</td>
<td>
<p align="center">Product B</p>
</td>
</tr>
<tr>
<td>
<p align="center">4</p>
</td>
<td>
<p align="center">123</p>
</td>
<td>
<p align="center">1</p>
</td>
<td>
<p align="center">Product C</p>
</td>
</tr>
</table>
<p>Each line has quantity one because throughout the application users would changed where a portion of an order was billed, shipped or assembled.  It seemed easier to simply store each as an individual line of quantity one than worry about how splitting lines would percolate data changes in the application.</p>
<p>What happens when you have quantity 100? How do you present that to the user?  How do you persist changes back to the database?  We realized the need to group like items for the user to avoid making him select 100 rows manually.  This led to, &#8220;How do we associate the one row in the UI with the corresponding 100 rows in the database?&#8221;.</p>
<p>The answer was relatively simple. Instead of storing a single id for the row, we stored all 100 ids comma delimited. </p>
<p>In grouping like items, we had to add a sub-query to select all the ids of the line item records aggregated for the result record.</p>
<p>In short:</p>
<pre name="code" class="sql">
select STUFF(
(
  SELECT ',' + convert(varchar(12), object_id)
  FROM sys.objects
  FOR xml PATH('')
), 1, 1, '')</pre>
<p>giving a result set of:</p>
<table>
<tr>
<td>4,5,7,8,13,15,&#8230;</td>
</tr>
</table>
<p>We&#8217;re selecting the id and converting it to a string.<br />
the For xml PATH(&#8221;) indicates that our output should be xml, but that the &#8220;path&#8221; for each record is an empty string.<br />
Given a result set of:</p>
<table>
<tr>
<td>4</td>
</tr>
<tr>
<td>5</td>
</tr>
<tr>
<td>7</td>
</tr>
<tr>
<td>8</td>
</tr>
<tr>
<td>13</td>
</tr>
<tr>
<td>15</td>
</tr>
</table>
<p>we &#8220;convert&#8221; it to an xml path of &#8220;&#8221; and get</p>
<table>
<tr>
<td>,4,5,7,8,13,15</td>
</tr>
</table>
<p>the STUFF function simply removes the first prepended &#8220;,&#8221; from our result.</p>
<p>Using this we were able to take user changes from the UI and apply them to the records in the database through a single UPDATE statement using the clause &#8220;where orderLineId in (@lineIds)&#8221;, @lineIds = our delimited listing.</p>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/19/concatenating-values-in-t-sql-select-statements/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Detecting and avoiding &#8220;A potentially dangerous Request.Form value was detected from the client&#8221; in asp.net</title>
		<link>http://www.blogfor.net/2008/04/19/detecting-and-avoiding-a-potentially-dangerous-requestform-value-was-detected-from-the-client-in-aspnet/</link>
		<comments>http://www.blogfor.net/2008/04/19/detecting-and-avoiding-a-potentially-dangerous-requestform-value-was-detected-from-the-client-in-aspnet/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 23:55:02 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=7</guid>
		<description><![CDATA[Leave requestValidation="true" and avoid invalid requests by validating user input at the business layer, at the client, and by stripping out invalid characters on postback.
]]></description>
			<content:encoded><![CDATA[<p>By default asp.net uses the setting validateRequests=&#8221;true&#8221;. This can lead to a paradox described here <a href="http://www.asp.net/learn/whitepapers/request-validation/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">http://www.asp.net/learn/whitepapers/request-validation/</a>. You can turn off request validation for your page or site, but that removes the basic protection asp.net provides against xss attacks. When you leave request validation on and a user enters text like &#8220;a&lt;b&#8221;, the request will error out long before it reaches your actual code.</p>
<p>As the article asp.net article suggests, one should always htmlEncode and htmlDecode inputs posted to and rendered from the server. In our case, our own employees had discovered our failure to do this. They promptly exploited it to give custom styling to data items. This made the customers happy, triggered a nightmarish conflict between those who considered this a &#8220;feature&#8221; and those who knew it was a &#8220;bug&#8221;. Once the users took enough advantage of this loophole, it became entrenched.</p>
<p>When we finally got a chance to do a major refactor, our first thought was, &#8220;well, let&#8217;s do as the article suggests and put htmlDecode and htmlEncode on every input where we bind controls against values from our database.&#8221; &#8211; this seemed tedious and did nothing to prevent future developers from opening new xss holes as we developed new features.</p>
<p>Our next idea was use of asp.net control adapters to override the default asp.net controls and perform the htmlEncode and htmlDecode automatically. This way, developers wouldn&#8217;t have to remember to do it themselves. Unfortunately, control adapters only apply to markup (ascx/aspx) and not to controls created/added in the codebehind.</p>
<p>We finally opted to leave it the asp.net request validation on and:</p>
<ol>
<li>add validation to every input to prevent markup from being posted</li>
<li>add validation in our business layer to prevent markup from entering our database</li>
<li>strip out characters from user inputs that make it invalid</li>
<li>use a third party control for entering rich text(markup). The control would handle the html encoding of the user input for us in these special cases and filter out invalid html tags.</li>
</ol>
<p>It helps to work with super smart people, one of whom happened to write an a nice validation framework that used another developer&#8217;s excellent code gen., so steps 1 and 2 were pretty easy once we came up with the proper regex.</p>
<p>First we need to find out what validation asp.net is doing against form values. This code can be found using <a href="http://www.aisto.com/roeder/dotnet/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.aisto.com');">reflector</a> in the System.Web.CrossSiteScripting class:</p>
<pre name="code" class="c-sharp">
internal static bool IsDangerousString(string s, out int matchIndex)
{
    matchIndex = 0;
    int startIndex = 0;
    while (true) {
        int num2 = s.IndexOfAny(startingChars, startIndex);
        if (num2 &lt; 0) {
            return false;
        }
        if (num2 == (s.Length - 1)) {
            return false;
        }
        matchIndex = num2;
        char ch = s[num2];
        if (ch != '&amp;') {
            if ((ch == '&lt;') &amp;&amp; ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == '!')) || (s[num2 + 1] == '/'))) {
                return true;
            }
        } else if (s[num2 + 1] == '#') {
            return true;
        }
        startIndex = num2 + 1;
    }
}</pre>
<p>If a word begins with an &#8220;&amp;#&#8221; or &#8220;&lt;&#8221; preceding an alpha, &#8220;!&#8221; or &#8220;/&#8221; character, then the value is considered invalid by asp.net.</p>
<p>For part 1 we created a custom validator that utilized the following javascript function:</p>
<pre name="code" class="javascript">
function NoXmlValidation(sender, args)
{
var re = new RegExp('(&amp;#)|(&lt;(?=(!|\\w|\\%|/)))', 'g');
args.IsValid = true;
if (args.Value &amp;&amp; args.Value.match(re)) {
args.IsValid = false;
}
return;
}</pre>
<p>Not all forms can be validated client side and prevent postback- specifically if you&#8217;re using validation groups and/or update panels, you can have major issues when the validators don&#8217;t fire and the postback generates the asp.net request validation error.<br />
To work around this, we hooked into the ms client side application framework. When an html form is submitted we go through the inputs and strip out characters that violate our xss validation.</p>
<p>First the javascript code:</p>
<pre name="code" class="javascript">
//called before onSubmit, validation should be called before, although the way we hooked into
//the event through the .net framework means that the code is also in there afterwards too
//but will never get called.
//This method goes through all the inputs and removes the characters that would cause a requestValidation exception on postback
//note: this actually modifies the element values, not just the data posted
function OnNormalSubmit() {
 // get all textarea and text inputs
 var inputs = $A(document.getElementsByTagName('input')).findAll(function(item) {return (item.type.toLowerCase() === 'text'); }).concat($A(document.getElementsByTagName('textarea')));
 var re = new RegExp('(&amp;#)|(&lt;(?=(!|\\w|\\%|/)))', 'g');
 // iterate through the all and replace invalid values
 inputs.each(
 		function(elt) {
 				elt.value=elt.value.replace(re,'');
 				if ( elt.Validators ) {
 					elt.Validators.each(
 						function(elt2) {
 							if ( elt2.isvalid !== undefined &amp;&amp; !elt2.isvalid ) {
 								$(elt2).hide();
 							}
 						}
 					);
 				}
 			}
 	);
}</pre>
<p>Note: the sample above uses the &#8220;<a href="http://prototypejs.org/api/utility/dollar-a" onclick="javascript:pageTracker._trackPageview('/outbound/article/prototypejs.org');">$A</a>&#8220;, &#8220;<a href="http://prototypejs.org/api/enumerable/each" onclick="javascript:pageTracker._trackPageview('/outbound/article/prototypejs.org');">each</a>&#8220;, and &#8220;<a href="http://prototypejs.org/api/enumerable/findAll" onclick="javascript:pageTracker._trackPageview('/outbound/article/prototypejs.org');">findAll</a>&#8220; methods in the <a href="http://prototypejs.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/prototypejs.org');">prototype</a> library.  &#8221;for&#8221; loops could be used instead, however, by using prototype we can abstract out the low level details and focus on the algorithm itself.</p>
<p>Now we need do is hook this method up to be called during the onPostback() method.<br />
In your pagebase or master, put in following code:</p>
<pre name="code" class="vb.net">
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
 If Not IsPostBack Then
 'register code for onSubmit validation to prevent requestValidationError. Note: must call ValidatorOnSubmit before calling custom code- otherwise the postback isn't prevented when the form is invalid.
 '.net puts our code before the standard ValidatorOnSubmit call, so we need to call it first manually.         

 ScriptManager.RegisterOnSubmitStatement(Me.Page, Me.GetType, "onSubmitScript", "if (typeof(ValidatorOnSubmit) === ""function"" &amp;&amp; ValidatorOnSubmit() == false) return false; " + Microsoft.VisualBasic.vbCr + "if( self['OnNormalSubmit'] ) { OnNormalSubmit(); return true; }" + Microsoft.VisualBasic.vbCr)         

 End If
End Sub</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/19/detecting-and-avoiding-a-potentially-dangerous-requestform-value-was-detected-from-the-client-in-aspnet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Detecting authentication cookie expiration on asyncronous requests</title>
		<link>http://www.blogfor.net/2008/04/19/detecting-authentication-cookie-expiration-on-asyncronous-requests/</link>
		<comments>http://www.blogfor.net/2008/04/19/detecting-authentication-cookie-expiration-on-asyncronous-requests/#comments</comments>
		<pubDate>Sat, 19 Apr 2008 23:33:15 +0000</pubDate>
		<dc:creator>phil</dc:creator>
				<category><![CDATA[asp.net]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=6</guid>
		<description><![CDATA[Handling authentication cookie expiration detection on asyncronous calls.]]></description>
			<content:encoded><![CDATA[<p>As functionality moves from postbacks and server side processing to the client via update panels and ajax behaviors, a common situation can occur when the user&#8217;s authentication cookie has expired and the user executes an asynchronous request. </p>
<p>Normally with a synchronous request, the web server will return a response with HTTP code 301 (redirect) and the browser will redirect the user to the login page.  However, for asynchronous requests, however, the server simply responds with an HTTP code of 500 (error).<br />
The ms ajax framework renders asynchronous requests as JSON rather than the standard SOAP.  This makes consuming server resources via javascript much easier.  The problem is that the ms ajax framework doesn&#8217;t distinguish between unhandled errors and authentication timeouts when processing requests as JSON.</p>
<p>The code that controls this is the class System.Web.Script.Services.RestHandler of the system.web.extensions assembly.</p>
<pre name="code" class="c-sharp">
internal static void ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData) {
	try
	{
		if (!s_permissionSetChecked) 	{
			s_permissionSet = (NamedPermissionSet) typeof(HttpRuntime).GetProperty("NamedPermissionSet", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null);
			s_permissionSetChecked = true;
		}
		if (s_permissionSet != null) 	{
			s_permissionSet.PermitOnly();
		}
		IDictionary<string,></string,> rawParams = GetRawParams(methodData, context);
		InvokeMethod(context, methodData, rawParams);
	} catch (Exception exception) {
		//THIS IS WHERE .NET CATCHES ALL EXCEPTIONS AND RETURNS THE 500 error
		WriteExceptionJsonString(context, exception);
	}
}                  

internal static void WriteExceptionJsonString(HttpContext context, Exception ex) {
	context.Response.ClearHeaders();
	context.Response.ClearContent();
	context.Response.Clear();
	context.Response.StatusCode = 500;
	context.Response.StatusDescription = HttpWorkerRequest.GetStatusDescription(500);
	context.Response.ContentType = "application/json";
	context.Response.AddHeader("jsonerror", "true");
	using (StreamWriter writer = new StreamWriter(context.Response.OutputStream, new UTF8Encoding(false)))
	{
		if (ex is TargetInvocationException) {
			ex = ex.InnerException;
		}
		if (context.IsCustomErrorEnabled) {
			writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(AtlasWeb.WebService_Error, string.Empty, string.Empty)));
		} else {
			writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(ex.Message, ex.StackTrace, ex.GetType().FullName)));
		}
		writer.Flush();
	}
}</pre>
<p>To get around this issue we need to detect JSON responses with HTTP code 500 and no authentication cookie in order to return our own slightly modified response. This is done with an http module.</p>
<pre name="code" class="vb.net">
Imports System                  

	Public Class SessionModule
		Implements IHttpModule                  

#Region " IHttpModule Implementation "                  

		Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init
			If context Is Nothing Then
				Throw New System.ArgumentNullException("context")
			End If                  

			AddHandler context.EndRequest, AddressOf OnEndRequest                  

		End Sub                  

#End Region                  

#Region " Private Methods "                  

		Private Sub OnEndRequest(ByVal sender As Object, ByVal e As EventArgs)
			'if this is a web service call with no auth cookie, send a different response than the generic error so that we can handle it appropriately
			'not the "customErrors" section defines (if not "off") that generic messages will be sent (including web services)
			'since it's a scriptHandler for asmx (for json/atlas) we can't get around that constraint with web service extensions (they never get hit)
			'so we do it here instead.
			'NOTE: we're returning a matching json object that asp.net is already configured to return (copied from reflector):
			'System.Web.Script.Services.RestHandler-&gt;WriteExceptionJsonString
			If System.IO.Path.GetExtension(System.Web.HttpContext.Current.Request.FilePath).ToLowerInvariant = ".asmx" AndAlso HttpContext.Current.Request.Cookies.Get(System.Web.Security.FormsAuthentication.FormsCookieName) Is Nothing Then
				WriteAccessDeniedExceptionJsonString(HttpContext.Current)
			End If
		End Sub                  

		Private Shared Sub WriteAccessDeniedExceptionJsonString(ByVal context As HttpContext)
			context.Response.ClearHeaders()
			context.Response.ClearContent()
			context.Response.Clear()
			context.Response.StatusCode = 500
			context.Response.StatusDescription = HttpWorkerRequest.GetStatusDescription(500)
			context.Response.ContentType = "application/json"
			context.Response.AddHeader("jsonerror", "true")
			Using writer As New System.IO.StreamWriter(context.Response.OutputStream, New UTF8Encoding(False))
				writer.Write(New WebServiceError("Authentication failed.", String.Empty, String.Empty).ToJson)
				writer.Flush()
			End Using
		End Sub                  

#End Region                  

#Region " Auth Cookie missing on Web Service request response "                  

		'this class is used to replicate the response from the .net framework when an json web service call
		'is denied because of missing auth ticket
		Private Class WebServiceError                  

#Region " Declarations "                  

			Private Const JsonTemplate As String = "{{""Message"":""{0}"",""StackTrace"":""{1}"",""ExceptionType"":""{2}""}}"
			Private _exceptionType As String
			Private _message As String
			Private _stackTrace As String                  

#End Region                  

#Region " Constructors "                  

			Public Sub New(ByVal msg As String, ByVal stack As String, ByVal type As String)
				_message = msg
				_stackTrace = stack
				_exceptionType = type
			End Sub                  

#End Region                  

#Region " Public Methods "                  

			Public Function ToJson() As String
				Return String.Format(System.Globalization.CultureInfo.InvariantCulture, JsonTemplate, _message, _stackTrace, _exceptionType)
			End Function                  

#End Region                  

		End Class                  

#End Region                  

	End Class</pre>
<p>Don&#8217;t forget to wire the http module into the asp.net pipeline using the httpModules section of the web.config.</p>
<p>Now, on the client side we need to hook a method into the asp.net ajax client side framework to listen for any http request that returns with our extra information (HTTP code=500 and Message=&#8221;Authentication failed&#8221;) and redirect the user accordingly. We can do this using the ms ajax application framework completedRequested event:</p>
<pre name="code" class="java">
// attaches a handler that is fired first after web service is returned, before specific handler is called
// specifically, if the web service errored because of authentication failure (auth cookie expired)
// then redirect the page to the login page.
// note the login page is hard coded is assumed to be in the path site/app path/login
Sys.Net.WebRequestManager.add_completedRequest(On_WebRequestCompleted);                  

function On_WebRequestCompleted(sender, eventArgs)
{
  if ( sender.get_statusCode() === 500 ) {
   if (sender.get_object().Message === "Authentication failed.") {
		window.location.href = window.location.protocol + "//" + window.location.host + window.location.pathname.substring(0,window.location.pathname.indexOf('/',1)) + '/login.aspx?redirectUrl=' + encodeURIComponent(window.location.pathname + window.location.search);
    }
  }
}</pre>
<p>This will redirect the user to page &#8220;login.aspx&#8221; and contain the current url as the redirectUrl querystring parameter.<br />
That&#8217;s it. Now when the user&#8217;s authentication expires he will be redirected to the login page as expected.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/19/detecting-authentication-cookie-expiration-on-asyncronous-requests/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ScrollTo using the ajax control toolkit animation framework</title>
		<link>http://www.blogfor.net/2008/04/06/scrollto-using-the-ajax-control-toolkit-animation-framework/</link>
		<comments>http://www.blogfor.net/2008/04/06/scrollto-using-the-ajax-control-toolkit-animation-framework/#comments</comments>
		<pubDate>Sun, 06 Apr 2008 18:44:58 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[ajaxcontroltoolkit]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[asp.net ajax]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=4</guid>
		<description><![CDATA[I&#8217;ve been digging deep into the asp.net ajax javascript framework and wanted to share one of the cool controls i was able to make using the asp.net ajax library and the AjaxControlToolkit animation framework.  The guys over at codeplex have put together a pretty nice animation framework.  It&#8217;s been pretty hard for me [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been digging deep into the asp.net ajax javascript framework and wanted to share one of the cool controls i was able to make using the asp.net ajax library and the AjaxControlToolkit animation framework.  The guys over at codeplex have put together a pretty nice animation framework.  It&#8217;s been pretty hard for me to find any useful reference material on the animation framework outside of using it really server side.  I wasn&#8217;t able to find anything about creating your own custom animation classes although the animation framework has obviously a ton of sample code.  Eventually i found my best resource to be VS2008 javascript intellisense with the aniamtion framework referenced into my class. Enough of the details, i could rant all day an may do so later but lets get into some of the cool stuff.</p>
<p><strong>javascript references for intellisense</strong></p>
<pre name="code" class="javascript">
/// <reference name="MicrosoftAjax.debug.js"></reference>
/// <reference name="MicrosoftAjaxTimer.debug.js"></reference>
/// <reference name="MicrosoftAjaxWebForms.debug.js"></reference>
/// <reference name="AjaxControlToolkit.ExtenderBase.BaseScripts.js" assembly="AjaxControlToolkit"></reference>
/// <reference name="AjaxControlToolkit.Common.Common.js" assembly="AjaxControlToolkit"></reference>
/// <reference name="AjaxControlToolkit.Common.DateTime.js" assembly="AjaxControlToolkit"></reference>
/// <reference name="AjaxControlToolkit.Animation.AnimationBehavior.js" assembly="AjaxControlToolkit"></reference>

/// <reference name="AjaxControlToolkit.Animation.Animations.js" assembly="AjaxControlToolkit"></reference></pre>
<p>specifically this sample doesn&#8217;t use the intellisense from all of these references but this is generally what i start with as my js references for any javascript class i&#8217;m looking to create. And yes, the intellisense builder requires that the js file references be in an order of dependence.  Ok, now we can finally move on to what i&#8217;m actually trying to blog about. The scroll to animation.</p>
<pre name="code" class="javascript">
Type.registerNamespace("boudreau");boudreau.scrollTo = function(element) {
    boudreau.scrollTo.initializeBase(this, [element]);
       this.animation = null;
}
boudreau.scrollTo.prototype = {
    initialize: function() {
    ///<summary>
    /// creates our animation and adds a click handler.
    ///</summary>
        boudreau.scrollTo.callBaseMethod(this, 'initialize');
        this.animation = new $AA.InterpolatedAnimation(this.get_element(), 2, 25, "scrollTop");
// Important: Notice that the value is passed as a function.
        // This overrides the animation's getAnimatedValue function.
        this.animation.getAnimatedValue = this.__getAnimatedValue;
    },

dispose: function() {
    ///<summary>
    /// Does the cleanup work
    //</summary>
        this.animation.dispose();
        boudreau.scrollTo.callBaseMethod(this, 'dispose');
    },

scrollTo : function( target ) {
    ///<summary>
    /// scrolls the container to to the target element.
    ///</summary>

        var container = this.get_element();
        // If we wanted the item to scroll to the middle of the
        // container we set offset = middle.
        var middle = ($common.getContentSize(container).height / 2.0 );

        // For now we just use a 40 pixel offset so it isn't hugging
        // the top of the container.
        var offset = 40;

        //set start and ending positions of the scroll window.
        this.animation.set_startValue(container.scrollTop);
        this.animation.set_endValue(target.offsetTop - 40);

        //let the framework do it's job.
        this.animation.play();

    },

__getAnimatedValue : funtion ( percentage ) {
        ///<summary>
        ///  This method is run in the context of the animation object.  Therefore it's
        ///  important to understand that when this function is executing that "this"
        ///  referes to the animation object, NOT the boudreau.scrollTo object.
        ///  Besides that this function performs a simple linear interpolation.
        ///</summary>
        ///<remarks>
        /// It's important to note the reason we have to define this function is that it's a
        ///  MustOverride on the InterpolatedAnimation object.
        ///  The reason i used InterpolatedAnimation is so that i could
        ///  implement a non-linear animation.
        ///</remarks>

        return this.get_startValue() + (this.get_endValue() - this.get_startValue()) * (percentage * / 100);

    }

}

boudreau.scrollTo.registerClass('boudreau.scrollTo', Sys.UI.Behavior);

if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();</pre>
<p><strong>That&#8217;s the code. </strong><br />
If you aren&#8217;t comfortable with prototypical development in javascript then you&#8217;ll you should brush up on that.  [Blog Link, WWW Link?] But if you are then lets dive into the details.</p>
<p><strong>The Behavior</strong><br />
<em>scrollTo object</em> derives from microsoft&#8217;s Sys.UI.Behavior which is used to extend the functionality of a particular DOM element. This behavior acts on the scrollable container you define as the target element. If someone asked me what this behavior did i&#8217;d tell them &#8221; It&#8217;s a javascript object that holds a reference to a DOM element,  the container, (This is what we get from microsoft ajax library.) The javascript object knows hows to scroll, with animation, to a given target element inside the container. &#8221;  If you can decipher that you&#8217;ve got it.   On to the gory details.</p>
<p><strong>The constructor &#8211; new $AA.InterpolatedAnimation()</strong><br />
In the <em>init</em> method we define a new InterpolatedAnimation first off $AA is a shorthand for AjaxControlToolkit.Animation, it saves us some 20 chars to type, and download for that matter.   The constructor used above takes some 7 parameters but we are only passing in 4 because i&#8217;m happy with the default values for the others for now.  The first, the target element, is the object that should contain the scrollBar you want to animate.  The second and third are fps and duration respectively (which i won&#8217;t discuss cause they are pretty self explanitory.) the fourth parameter is the property of the the target element you want to animate using the InterpolatedAnimation.  Kind of important to understand what&#8217;s going on here, this parameter is what the interpolated animation updates when it is told to .play().  So, in our case we want to animate the scrollTop property of the target element.  scrollTop is just a javascript property that gets/sets the top of the content area in a scrollable window.  Alright, that&#8217;s creating the animation.  Hopefully you see what&#8217;s going on here, lets recap.  We are creating an interpolated animation object inside of our behavior and telling it what property on what element we want to animate.  Next we&#8217;ll look at the scrollTo function and see how the behavior does the work.</p>
<p><strong>The worker &#8211; scrollTo()</strong><br />
the<em> scrollTo()</em> method does all the work of finding and scrolling to the correct distance inside the container.  At the end we hope to see that our target element is 40 px below the scrollTop of the container content window.  First we define the properties on the animation that will be interpolated, the start and end scrollTop value of the container.  These two properties on the InterpolatedAnimation are the values you want the animation to interpolate across. (remember how we set scrollTop as the property in the constructor.) Our InterpolatedAnimation  is going to interpolate the values between start_value and end_value on the container element (the scrollable element) and update the property scrollTop with the value at each step in the animation.  This is how it works, if you don&#8217;t understand the previous explanation read it again, it&#8217;s the magic and hopefully you can tell there is no real <em>magic</em> at all!</p>
<pre name="code" class="javascript">
// For now we just use a 40 pixel offset so it isn't hugging
// the top of the container.
var offset = 40;

//set start and ending positions of the scroll window.
this.animation.set_startValue(container.scrollTop);
this.animation.set_endValue(target.offsetTop - 40);

this.animation.play();</pre>
<p>So that&#8217;s pretty much it, after you</p>
<pre name="code" class="javascript">$create(boudreau.scrollTo, null,null,null, $get(scrollableElementId))</pre>
<p>a scrollTo behavior on a scrollable element you use</p>
<pre name="code" class="javascript">
$find(scrollableElementId).scrollTo(element_to_scroll_to_in_container)</pre>
<p>to produce a nice smooth scroll to the target element inside the scrollable container.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2008/04/06/scrollto-using-the-ajax-control-toolkit-animation-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Grand Opening, Google Syntax Highlighter Fix</title>
		<link>http://www.blogfor.net/2007/12/12/grand-opening/</link>
		<comments>http://www.blogfor.net/2007/12/12/grand-opening/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 06:16:47 +0000</pubDate>
		<dc:creator>andrew</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[lorem ipsum]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.blogfor.net/?p=3</guid>
		<description><![CDATA[ The blog is up and running and with the first post comes some interesting info on setting up syntax highlighting. So, I finally got the google syntax highlighter working with my wordpress install HOORAY.
Google Syntax Highlighter for WordPress
http://wordpress.org/extend/plugins/google-syntax-highlighter/
doing some pretty simple testing i tracked down the footer wasn&#8217;t adding it&#8217;s code to wordpress. So [...]]]></description>
			<content:encoded><![CDATA[<p> The blog is up and running and with the first post comes some interesting info on setting up syntax highlighting. So, I finally got the google syntax highlighter working with my wordpress install HOORAY.</p>
<p><strong>Google Syntax Highlighter for WordPress<br />
http://wordpress.org/extend/plugins/google-syntax-highlighter/</strong></p>
<p>doing some pretty simple testing i tracked down the footer wasn&#8217;t adding it&#8217;s code to wordpress. So i looked at how other people had hooked the footer event and then just did that.</p>
<p>Something has changed with wordpress since Peter Ryan last updated his wordpress plugin, so i fixed it. Seems that the footer load event changed or the one he was using was deprecated?  I haven&#8217;t the slightest idea since today was the first day i&#8217;ve seen wordpress code, nor do i really care now that it&#8217;s working.<br />
<strong>Original Code: google_syntax_highlighter.php</strong></p>
<pre name="code" class="php">
add_action('wp_footer','insert_footer');</pre>
<p><strong>Working Code: google_syntax_highlighter.php</strong></p>
<pre name="code" class="php">
add_action('get_footer','insert_footer');</pre>
<p><span id="more-3"></span><br />
The good stuff has arrived.</p>
<pre name="code" class="vb">
Private Function DetermineRenderClientScript() As Boolean
  If Not Me._renderClientScriptValid Then
    Me._renderClientScript = False
    If Me.EnableSortingAndPagingCallbacks AndAlso Me.Page.Request.Browser.SupportsCallback Then
      Dim browser As HttpBrowserCapabilities = Me.Page.Request.Browser
      Dim flag As Boolean = (browser.EcmaScriptVersion.Major &gt; 0)
      Dim flag2 As Boolean = (browser.W3CDomVersion.Major &gt; 0)
      Dim flag3 As Boolean = Not StringUtil.EqualsIgnoreCase(browser.Item("tagwriter"), GetType(Html32TextWriter).FullName)
      Me._renderClientScript = ((flag AndAlso flag2) AndAlso flag3)
    End If
    Me._renderClientScriptValid = True
  End If
  Return Me._renderClientScript
End Function</pre>
<p>this is testing the code markup</p>
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque sed felis. Aliquam sit amet felis. Mauris semper, velit semper laoreet dictum, quam diam dictum urna, nec placerat elit nisl in quam. Etiam augue pede, molestie eget, rhoncus at, convallis ut, eros. Aliquam pharetra. Nulla in tellus eget odio sagittis blandit. Maecenas at nisl. Nullam lorem mi, eleifend a, fringilla vel, semper at, ligula. Mauris eu wisi. Ut ante dui, aliquet nec, congue non, accumsan sit amet, lectus. Mauris et mauris. Duis sed massa id mauris pretium venenatis. Suspendisse cursus velit vel ligula. Mauris elit. Donec neque. Phasellus nec sapien quis pede facilisis suscipit. Aenean quis risus sit amet eros volutpat ullamcorper. Ut a mi. Etiam nulla. Mauris interdum.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogfor.net/2007/12/12/grand-opening/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
