<?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>Chris Fulstow &#187; Chris Fulstow</title>
	<atom:link href="http://chrisfulstow.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://chrisfulstow.com</link>
	<description>ASP.NET Tech Lead and Web Developer</description>
	<lastBuildDate>Sat, 05 Jun 2010 01:32:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using the IIS 7 URL Rewrite Module to block crawlers</title>
		<link>http://chrisfulstow.com/using-the-iis-7url-rewrite-module-to-block-crawlers/</link>
		<comments>http://chrisfulstow.com/using-the-iis-7url-rewrite-module-to-block-crawlers/#comments</comments>
		<pubDate>Sat, 05 Jun 2010 01:32:55 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[iis]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=370</guid>
		<description><![CDATA[Here’s an easy way to block the main web crawlers &#8211; Google Bing and Yahoo &#8211; from indexing any site across an entire server.  This is really useful if you push all your beta builds to a public facing server, but don&#8217;t want them indexed yet by the search engines.
1. Install the IIS URL Rewrite Module.
2. <a href="http://chrisfulstow.com/using-the-iis-7url-rewrite-module-to-block-crawlers/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Here’s an easy way to block the main web crawlers &#8211; Google Bing and Yahoo &#8211; from indexing any site across an entire server.  This is really useful if you push all your beta builds to a public facing server, but don&#8217;t want them indexed yet by the search engines.</p>
<p>1. Install the <a href="http://www.iis.net/download/URLRewrite" target="_blank">IIS URL Rewrite Module</a>.</p>
<p>2. At the server level, add a request blocking rule.  Block user-agent headers matching the regex: <em>googlebot|msnbot|slurp</em>.</p>
<p>Or, just paste this rule into &#8220;C:\Windows\System32\inetsrv\config\applicationHost.config&#8221;</p>
<pre class="brush: xml;">
&lt;system.webServer&gt;
   &lt;rewrite&gt;
      &lt;globalRules&gt;
         &lt;rule name=&quot;RequestBlockingRule1&quot; stopProcessing=&quot;true&quot;&gt;
            &lt;match url=&quot;.*&quot; /&gt;
            &lt;conditions&gt;
               &lt;add input=&quot;{HTTP_USER_AGENT}&quot; pattern=&quot;googlebot|msnbot|slurp&quot; /&gt;
            &lt;/conditions&gt;
            &lt;action type=&quot;CustomResponse&quot; statusCode=&quot;403&quot;
               statusReason=&quot;Forbidden: Access is denied.&quot;
               statusDescription=&quot;You do not have permission to view this page.&quot; /&gt;
         &lt;/rule&gt;
      &lt;/globalRules&gt;
   &lt;/rewrite&gt;
&lt;/system.webServer&gt;
</pre>
<p>This’ll block Google, Bing and Yahoo from indexing any site published on the server.  To test it out, try the Firefox <a href="https://addons.mozilla.org/en-US/firefox/addon/59/" target="_blank">User Agent Switcher</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/using-the-iis-7url-rewrite-module-to-block-crawlers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Counting blank lines in a large text file with C# and .NET</title>
		<link>http://chrisfulstow.com/counting-blank-lines-in-a-large-text-file-with-csharp-and-dotnet/</link>
		<comments>http://chrisfulstow.com/counting-blank-lines-in-a-large-text-file-with-csharp-and-dotnet/#comments</comments>
		<pubDate>Sun, 16 May 2010 03:30:58 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=326</guid>
		<description><![CDATA[There are a few different ways in .NET to count the number of blank lines in a text file, but which is the most efficient?
To test some different approaches, I&#8217;ve written this function to create a huge text file with some empty lines.  To verify that my counting functions give correct results, I need this <a href="http://chrisfulstow.com/counting-blank-lines-in-a-large-text-file-with-csharp-and-dotnet/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>There are a few different ways in .NET to count the number of blank lines in a text file, but which is the most efficient?</p>
<p>To test some different approaches, I&#8217;ve written this function to create a huge text file with some empty lines.  To verify that my counting functions give correct results, I need this function to create a file with a specific number of blank lines.</p>
<pre class="brush: csharp;">
private static void BuildFileWithBlankLines(string path, uint blanks)
{
    var random = new Random();
    var counter = 0;

    using (var sw = File.CreateText(path))
    {
        while (counter &lt; blanks)
        {
            var isBlank = (random.Next(100) == 0);  // ~1% of lines blank
            sw.WriteLine(isBlank ? &quot;&quot; : &quot;NOT BLANK&quot;);
            if (isBlank) { counter++; }
        }
    }
}
</pre>
<p>For my test, I&#8217;ve used 250,000 empty lines, which outputs a file just over 250 MB.  This should be big enough to expose the differences between counting methods.</p>
<h3>1. Regular expression matching in memory</h3>
<pre class="brush: csharp;">
var content = File.ReadAllText(path);
var re = new Regex(@&quot;^\r?\n&quot;, RegexOptions.Multiline);
var count = re.Matches(content).Count;
</pre>
<p>This technique loads the whole text file into a string variable using <a href="http://msdn.microsoft.com/en-us/library/ms143368.aspx">File.ReadAllText</a>, which is really just a wrapper for <a href="http://msdn.microsoft.com/en-us/library/system.io.streamreader.readtoend.aspx">StreamReader.ReadToEnd.</a> It loads the character bytes from a file stream into a <a href="http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx">StringBuilder</a>.  The load is relatively quick, taking about 8% of the total processing time.  Once the file is loaded into memory, a regular expression finds and counts all the blank lines. This is, not surprisingly, glacially slow.  Total duration was 16,531 ms.</p>
<h3>2. Counting line by line through a string array</h3>
<pre class="brush: csharp;">
var count = File.ReadAllLines(path).Count(s =&gt; s.Length == 0);
</pre>
<p>I like this approach because it&#8217;s simple and readable.  The first step is similar to the above, but this time uses a StreamReader (via <a href="http://msdn.microsoft.com/en-us/library/s2tte0y1.aspx">File.ReadAllLines</a>) to load the file into a string array, rather than into a single string. <a href="http://msdn.microsoft.com/en-us/library/bb535181(v=VS.100).aspx">IEnumerable.Count</a> then loops through the array and tries to match each line against a predicate that checks for empty strings.  This takes less than half the time of the regex approach, only 7,006 ms.</p>
<h3>3. Streaming through the file</h3>
<pre class="brush: csharp;">
uint count = 0;
using (var sr = File.OpenText(path))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {
        if (line.Length == 0) { count++; }
    }
}
</pre>
<p>Unlike the first two, this last approach doesn&#8217;t load the entire file into memory.  It uses <a href="http://msdn.microsoft.com/en-us/library/z13csk76(v=VS.100).aspx">File.OpenText</a> to create a new StreamReader, then reads each line from the FileStream counting blank lines as it goes along.  This is blazing fast compared to the other two, taking just 2,108 ms.</p>
<h3>Conclusion</h3>
<p>There&#8217;s almost an order of magnitude difference between the best and worst methods.  So if you&#8217;re working with large files, try not to load them into memory first, but stream directly from disk instead.</p>
<p><img src="http://chart.apis.google.com/chart?cht=bhs&amp;chd=t:16531,7006,2108&amp;chs=400x150&amp;chds=0,20000&amp;chco=FF0000|FF9E0C|21B703&amp;chxt=x,y&amp;chxr=0,0,20000&amp;chxl=1:|Stream|String array|Regex&amp;chbh=a" alt="Test speeds" /></p>
<p>This applies especially to parsing large data files before loading them into a database.  In some cases, it&#8217;s not just slow to load into memory first, but impossible.</p>
<p>For example, a 500 GB XML file wouldn&#8217;t load easily into an <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.aspx">XDocument</a>, but could be streamed with an <a href="http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx">XmlReader</a> and parsed with <a href="http://msdn.microsoft.com/en-us/library/system.xml.linq.xnode.readfrom.aspx">XNode.ReadFrom</a>. Similarly, a huge CSV file couldn&#8217;t be loaded easily into a string then <a href="http://msdn.microsoft.com/en-us/library/system.string.split.aspx">String.Split</a> all in one go.  Instead, you&#8217;d probably parse it line by line with a StreamReader, or use a streaming <a href="http://www.codeproject.com/KB/database/CsvReader.aspx">CsvReader</a> library.</p>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/counting-blank-lines-in-a-large-text-file-with-csharp-and-dotnet/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Customising Visual Studio debugger DataTips with DebuggerDisplay</title>
		<link>http://chrisfulstow.com/customising-visual-studio-debugger-datatips-with-debuggerdisplay/</link>
		<comments>http://chrisfulstow.com/customising-visual-studio-debugger-datatips-with-debuggerdisplay/#comments</comments>
		<pubDate>Wed, 17 Feb 2010 23:40:12 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=315</guid>
		<description><![CDATA[The DebuggerDisplay attribute lets you change how an object is displayed in the Visual Studio debugger. Take these two simple classes representing a Company and an Employee.

public class Company
{
    public string Name { get; set; }
    public string StockSymbol { get; set; }
    public IEnumerable&#60;Employee&#62; Employees <a href="http://chrisfulstow.com/customising-visual-studio-debugger-datatips-with-debuggerdisplay/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.debuggerdisplayattribute.aspx">DebuggerDisplay</a> attribute lets you change how an object is displayed in the Visual Studio debugger. Take these two simple classes representing a <em>Company</em> and an <em>Employee</em>.</p>
<pre class="brush: csharp;">
public class Company
{
    public string Name { get; set; }
    public string StockSymbol { get; set; }
    public IEnumerable&lt;Employee&gt; Employees { get; set; }
    public Company(string name) { Name = name; }
}

public class Employee
{
    public string Name { get; set; }
    public Employee(string name) { Name = name; }
}
</pre>
<p>Create and initialise a new Company object with some data.</p>
<pre class="brush: csharp;">
var company = new Company(&quot;Microsoft&quot;)
{
    StockSymbol = &quot;MSFT&quot;,
    Employees = new List&lt;Employee&gt;
    {
        new Employee(&quot;Anders Hejlsberg&quot;),
        new Employee(&quot;Steve Ballmer&quot;),
        new Employee(&quot;Scott Guthrie&quot;)
    }
};
</pre>
<p>Now, if you break into the code and start a debug session, you can hover over the company object to reveal its debugger DataTip.  By expanding the nodes you can drill down into the object&#8217;s data.</p>
<p><img class="alignnone size-full wp-image-319" title="Visual Studio debug hover" src="http://chrisfulstow.com/wp-content/uploads/2010/02/debug-hover1.png" alt="Visual Studio debug hover" width="354" height="173" /></p>
<p>The default information shown in the DataTip, although useful, can be improved by decorating classes with the DebuggerDisplay attribute.  For companies, it might be useful to to display their Name and StockSymbol instead of the object type <em>{Company}</em>.</p>
<pre class="brush: csharp;">
[DebuggerDisplay(&quot;{Name} - {StockSymbol}&quot;)]
public class Company
</pre>
<p>The same goes for the Employee object.  We can show the employee name instead of the type <em>{Employee}</em>.</p>
<pre class="brush: csharp;">
[DebuggerDisplay(&quot;{Name}&quot;)]
public class Employee
</pre>
<p>The result is a more useful and descriptive view of your Company objects.</p>
<p><img class="alignnone size-full wp-image-321" title="Visual Studio debug hover" src="http://chrisfulstow.com/wp-content/uploads/2010/02/debug-hover-2.png" alt="Visual Studio debug hover with DebuggerDisplay attribute" width="353" height="190" /></p>
<p>For more info about customising Visual Studio&#8217;s debugger DataTips, see this article from MSDN Magazine:</p>
<ul>
<li><a href="http://msdn.microsoft.com/en-us/magazine/cc163974.aspx">DataTips, Visualizers and Viewers Make Debugging .NET Code a Breeze</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/customising-visual-studio-debugger-datatips-with-debuggerdisplay/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fibonacci numbers iterator with C# yield statements</title>
		<link>http://chrisfulstow.com/fibonacci-numbers-iterator-with-csharp-yield-statements/</link>
		<comments>http://chrisfulstow.com/fibonacci-numbers-iterator-with-csharp-yield-statements/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 02:41:21 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=311</guid>
		<description><![CDATA[Here&#8217;s a C# iterator for generating the sequence of Fibonacci numbers.  It uses the yield return statement to pass back each number in turn.  By default, the arithmetic addition won&#8217;t throw an exception when previous + current is greater than UInt64.MaxValue, so I&#8217;m using a checked expression to enable overflow checking.

public static IEnumerable&#60;ulong&#62; FibonacciNumbers()
{
  <a href="http://chrisfulstow.com/fibonacci-numbers-iterator-with-csharp-yield-statements/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a C# iterator for generating the sequence of <a href="http://en.wikipedia.org/wiki/Fibonacci_number">Fibonacci numbers</a>.  It uses the <a href="http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx">yield return</a> statement to pass back each number in turn.  By default, the arithmetic addition won&#8217;t throw an exception when <em>previous + current</em> is greater than <a href="http://msdn.microsoft.com/en-us/library/system.uint64.maxvalue.aspx">UInt64.MaxValue</a>, so I&#8217;m using a <a href="http://msdn.microsoft.com/en-us/library/74b4xzyw.aspx">checked expression</a> to enable overflow checking.</p>
<pre class="brush: csharp;">
public static IEnumerable&lt;ulong&gt; FibonacciNumbers()
{
    yield return 0;
    yield return 1;

    ulong previous = 0, current = 1;
    while (true)
    {
        ulong next = checked(previous + current);
        yield return next;
        previous = current;
        current = next;

    }
}
</pre>
<p>We can use the iterator with a foreach loop until it throws an OverflowException.</p>
<pre class="brush: csharp;">
try
{
    foreach (ulong i in FibonacciNumbers())
    {
        Console.WriteLine(&quot;{0:0,0}&quot;, i);
    }
}
catch (OverflowException)
{
    Console.WriteLine(&quot;Sorry, the next number is too big.&quot;);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/fibonacci-numbers-iterator-with-csharp-yield-statements/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Building a string of repeated characters in C#</title>
		<link>http://chrisfulstow.com/building-a-string-of-repeated-characters-in-csharp/</link>
		<comments>http://chrisfulstow.com/building-a-string-of-repeated-characters-in-csharp/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 08:12:36 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=309</guid>
		<description><![CDATA[As many different techniques as I could think of for making a string of repeated characters in C#.

char ch = 'A';
int count = 100;

// clean and concise, using the string contructor overload
var spaces1 = new string(ch, count);

// using Enumerable.Repeat to build a list of spaces,
// then folding them into a string
var spaces2 = Enumerable.Repeat(ch, count).Aggregate(&#34;&#34;, <a href="http://chrisfulstow.com/building-a-string-of-repeated-characters-in-csharp/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>As many different techniques as I could think of for making a string of repeated characters in C#.</p>
<pre class="brush: csharp;">
char ch = 'A';
int count = 100;

// clean and concise, using the string contructor overload
var spaces1 = new string(ch, count);

// using Enumerable.Repeat to build a list of spaces,
// then folding them into a string
var spaces2 = Enumerable.Repeat(ch, count).Aggregate(&quot;&quot;, (s,c) =&gt; s+c);

// brute force of looping into a StringBuilder
var sb = new StringBuilder(count);
for (int i = 0; i &lt; count; i++) { sb.Append(ch); }
var spaces3 = sb.ToString();

// building an array of strings, then joining without a delimiter
var spacesArray = Enumerable.Repeat(ch.ToString(), count).ToArray();
var spaces4 = string.Join(string.Empty, spacesArray);

// dirty hack with StringBuilder.Insert
var spaces5 = new StringBuilder().Insert(0, ch.ToString(), count).ToString();

// succinct hack with String.PadRight
var spaces6 = string.Empty.PadRight(count, ch);

// using ArrayList.Repeat to build the array of repeated strings
// then smushing with String.Concat
var arrayList = ArrayList.Repeat(ch, count).ToArray();
var spaces7 = string.Concat(arrayList);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/building-a-string-of-repeated-characters-in-csharp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Examples of C# Object Initializers</title>
		<link>http://chrisfulstow.com/examples-of-csharp-object-initializers/</link>
		<comments>http://chrisfulstow.com/examples-of-csharp-object-initializers/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 08:14:42 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=304</guid>
		<description><![CDATA[A selection of the various C# object initialization syntaxes:

// explicit shorthand array, C# 1.0 style
int[] numbersIntArray1 = { 4, 8, 15, 16, 23, 42 };

// two dimensional 3x2 array
int[,] numbersInt3x2Array = { { 4, 8 }, { 15, 16 }, { 23, 42 } };

// implicitly typed array
var numbersIntArray2 = new[] { 4, 8, 15, <a href="http://chrisfulstow.com/examples-of-csharp-object-initializers/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>A selection of the various C# object initialization syntaxes:</p>
<pre class="brush: csharp;">
// explicit shorthand array, C# 1.0 style
int[] numbersIntArray1 = { 4, 8, 15, 16, 23, 42 };

// two dimensional 3x2 array
int[,] numbersInt3x2Array = { { 4, 8 }, { 15, 16 }, { 23, 42 } };

// implicitly typed array
var numbersIntArray2 = new[] { 4, 8, 15, 16, 23, 42 };

// typed array with an implicitly type variable
var numbersDoubleArray = new double[] { 4, 8, 15, 16, 23, 42 };

// generic List&lt;&gt;
var numbersList = new List&lt;int&gt; { 4, 8, 15, 16, 23, 42 };

// generic HashSet&lt;&gt;
var numbersHashSet = new HashSet&lt;int&gt; { 4, 8, 15, 16, 23, 42 };

// generic Dictionary
var dictionary = new Dictionary&lt;int, string&gt;
{
    { 4, &quot;four&quot; },
    { 8, &quot;eight&quot; },
    { 15, &quot;fifteen&quot; },
    { 16, &quot;sixteen&quot; },
    { 23, &quot;twenty three&quot; },
    { 42, &quot;fourty two&quot; }
};

// implicitly typed array of System.Uri objects
var searchEngines = new[]
{
    new Uri(&quot;http://www.google.com/&quot;),
    new Uri(&quot;http://www.bing.com/&quot;),
    new Uri(&quot;http://www.yahoo.com/&quot;)
};

// implicitly typed array of an anonymous type
var complexNumbers = new[]
{
    new { Real = 4, Imaginary = 7 },
    new { Real = -10, Imaginary = 3 },
};

// implicitly typed array of System.Func&lt;&gt; delegates
var operations = new Func&lt;int, int&gt;[]
{
    (x =&gt; x * x),
    (x =&gt; x + x)
};

// nested object initializers
var smtpClient = new SmtpClient
{
    Host = &quot;mail.example.com&quot;,
    Port = 25,
    Credentials = new NetworkCredential
    {
        UserName = &quot;MailScheduler&quot;,
        Password = @&quot;%yI2Ei5GL0&quot;
    }
};

// implicitly typed jagged array of strings
var jaggedArray = new[]
{
    new[] {&quot;Jack&quot;, &quot;Sayid&quot;, &quot;Hurley&quot;, &quot;Miles&quot;},
    new[] {&quot;Sawyer&quot;, &quot;Kate&quot;}
};

// implicitly typed array of objects implementing IEnumerable&lt;int&gt;
var listOfLists = new IEnumerable&lt;int&gt;[]
{
    new List&lt;int&gt; {4, 8, 15, 16, 23, 42},
    new Collection&lt;int&gt; { 4, 8, 15, 16, 23, 42 },
    new int[] {4, 8, 15, 16, 23, 42 }
};
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/examples-of-csharp-object-initializers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Snack size C#: null coalescing operator</title>
		<link>http://chrisfulstow.com/snack-size-c-null-coalescing-operator/</link>
		<comments>http://chrisfulstow.com/snack-size-c-null-coalescing-operator/#comments</comments>
		<pubDate>Sat, 13 Feb 2010 00:08:04 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[c#]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=289</guid>
		<description><![CDATA[You need to assign the value of an expression to a variable, unless that expression evaluates to null, in which case default to something else.  And if that something else is also null, then fall back to another value, and so on.
For example, a web page that uses a theme setting to control look-and-feel.  If <a href="http://chrisfulstow.com/snack-size-c-null-coalescing-operator/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>You need to assign the value of an expression to a variable, unless that expression evaluates to null, in which case default to something else.  And if that something else is also null, then fall back to another value, and so on.</p>
<p>For example, a web page that uses a theme setting to control look-and-feel.  If the user has selected their own theme then use that; otherwise use the site&#8217;s default theme; or, if that&#8217;s not defined, use the global theme; or finally if no global theme is defined then fall back to a system default.</p>
<h3>The long, readable version</h3>
<p>Using good, old fashioned, conditional logic.</p>
<pre class="brush: csharp;">
string theme;
if (userTheme != null)
{
    theme = userTheme;
}
else if (siteTheme != null)
{
    theme = siteTheme;
}
else if (globalTheme != null)
{
    theme = globalTheme;
}
else
{
    theme = defaultTheme;
}
</pre>
<h3>The shorter, slightly befuddling version</h3>
<p>By nesting the ternary conditional operator in a most disagreeable way.</p>
<pre class="brush: csharp;">
string theme =
    userTheme != null ? userTheme
    : siteTheme != null ? siteTheme
    : globalTheme != null ? globalTheme
    : defaultTheme;
</pre>
<h3>The deluxe C# 3.0 version</h3>
<p>With the overkill of an implicitly-typed array, an IEnumerable extension method, and a lambda predicate.</p>
<pre class="brush: csharp;">
string theme = new [] {
    userTheme, siteTheme, globalTheme, defaultTheme
}.First(t =&gt; t != null);
</pre>
<h3>The elegant coalescence version</h3>
<p>With C# 2.0&#8217;s <a href="http://msdn.microsoft.com/en-us/library/ms173224.aspx">null-coalescing operator</a>, doing what it does best.</p>
<pre class="brush: csharp;">
string theme = userTheme ?? siteTheme ?? globalTheme ?? defaultTheme;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/snack-size-c-null-coalescing-operator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Free Microsoft certification beta exams coming soon</title>
		<link>http://chrisfulstow.com/free-microsoft-certification-beta-exams-coming-soon/</link>
		<comments>http://chrisfulstow.com/free-microsoft-certification-beta-exams-coming-soon/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 06:23:34 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=286</guid>
		<description><![CDATA[New beta Microsoft certification exams available free between March 31, 2010 and April 20, 2010.

70-515 TS: Web Applications Development with Microsoft® .NET Framework 4
70-516 TS: Accessing Data with Microsoft® .NET Framework 4
70-513 TS: Windows Communication Foundation Development with Microsoft® .NET Framework 4
70-519 Pro: Designing and Developing Web Applications using Microsoft® .NET Framework 4

More info on <a href="http://chrisfulstow.com/free-microsoft-certification-beta-exams-coming-soon/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>New beta Microsoft certification exams available free between March 31, 2010 and April 20, 2010.</p>
<ul>
<li>70-515 TS: Web Applications Development with Microsoft® .NET Framework 4</li>
<li>70-516 TS: Accessing Data with Microsoft® .NET Framework 4</li>
<li>70-513 TS: Windows Communication Foundation Development with Microsoft® .NET Framework 4</li>
<li>70-519 Pro: Designing and Developing Web Applications using Microsoft® .NET Framework 4</li>
</ul>
<p>More info on Gerry O&#8217;Brien&#8217;s blog here: <a href="http://blogs.msdn.com/gerryo/archive/2010/02/10/free-certification-exams.aspx">Free Certification Exams</a></p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;"><em>70-511 TS: Windows Applications Development with Microsoft® .NET Framework 4<br />
70-513 TS: Windows Communication Foundation Development with Microsoft® .NET Framework 4<br />
70-515 TS: Web Applications Development with Microsoft® .NET Framework 4<br />
70-516 TS: Accessing Data with Microsoft® .NET Framework 4<br />
70-519 Pro: Designing and Developing Web Applications using Microsoft® .NET Framework 4</em></div>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/free-microsoft-certification-beta-exams-coming-soon/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TableHeaderScope.Column and HTML standards compliance</title>
		<link>http://chrisfulstow.com/tableheaderscope-column-and-html-standards-compliance/</link>
		<comments>http://chrisfulstow.com/tableheaderscope-column-and-html-standards-compliance/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 01:28:28 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=270</guid>
		<description><![CDATA[Neil spotted this quirky behaviour in the TableHeaderCell control. Suppose you&#8217;ve got a Table web control that renders a &#60;table&#62; tag with a &#60;th scope=&#8221;col&#8221;&#62;, using code something like this:

Table table = new Table()
{
    Rows =
    {
        new TableRow()
    <a href="http://chrisfulstow.com/tableheaderscope-column-and-html-standards-compliance/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>Neil spotted this <a href="http://www.neilpullinger.co.uk/2008/05/tableheaderscope-enum-does-not-generate.html">quirky behaviour in the TableHeaderCell</a> control. Suppose you&#8217;ve got a <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.table.aspx">Table web control</a> that renders a &lt;table&gt; tag with a &lt;th scope=&#8221;col&#8221;&gt;, using code something like this:</p>
<pre class="brush: csharp;">
Table table = new Table()
{
    Rows =
    {
        new TableRow()
        {
            Cells =
            {
                new TableHeaderCell()
                    { Scope = TableHeaderScope.Column, Text = &quot;MyColumn&quot; }
            }
        }
    }
};
</pre>
<p>Then the rendered HTML won&#8217;t be W3C compliant because a <em>scope</em> value of &#8220;column&#8221; isn&#8217;t valid:</p>
<pre class="brush: xml;">
&lt;table border=&quot;0&quot;&gt;
    &lt;tr&gt;
        &lt;th scope=&quot;column&quot;&gt;&lt;/th&gt;
    &lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>According to the W3C <a href="http://www.w3.org/TR/html401/struct/tables.html#h-11.2.6">HTML</a> and <a href="http://www.w3.org/TR/2001/REC-xhtml-modularization-20010410/abstract_modules.html#sec_5.6.">XHTML</a> specs, the acceptable values for <em>scope</em> are [row|col|rowgroup|colgroup]. This is confirmed by the <a href="http://validator.w3.org/">W3C Markup Validation Service</a>, which reports the error:</p>
<p><img class="alignnone size-full wp-image-269" title="W3 TH error" src="http://chrisfulstow.com/wp-content/uploads/2010/02/w3-th-error.png" alt="W3 TH error" width="603" height="242" /></p>
<p>Stepping into the source code for the <a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.tableheadercell.aspx">TableHeaderCell</a> control with <a href="http://www.aisto.com/roeder/dotnet/">Reflector</a> or the <a href="http://blogs.msdn.com/sburke/archive/2008/01/16/configuring-visual-studio-to-debug-net-framework-source-code.aspx">.NET Reference Source</a>, you can see the root of the problem:</p>
<pre class="brush: csharp;">
protected override void AddAttributesToRender(HtmlTextWriter writer)
{
    TableHeaderScope scope = Scope;

    if (scope != TableHeaderScope.NotSet)
    {
        writer.AddAttribute(HtmlTextWriterAttribute.Scope,
            scope.ToString().ToLowerInvariant());
    }
}
</pre>
<p>When the control sets the scope attribute&#8217;s value, it uses a lowercase string representation of the TableHeaderScope.Column enumeration, i.e. &#8220;column&#8221;. An enum value of TableHeaderScope.Col would&#8217;ve been ok, but TableHeaderScope.Column is invalid.</p>
<h2>Workarounds</h2>
<p>Neil has a good workaround by adding the scope attribute manually instead of using the TableHeaderCell.Scope property:</p>
<pre class="brush: csharp;">
TableHeaderCell th = new TableHeaderCell();
th.Attributes[&quot;scope&quot;] = &quot;col&quot;;
</pre>
<p>I thought I&#8217;d have a go at extending this fix into a simple <a href="http://msdn.microsoft.com/en-us/magazine/cc163543.aspx">control adatper</a> that makes sure TableHeaderCell always renders itself correctly. It works by checking whether the Scope property is set to TableHeaderScope.Column, and if so manually adds the attribute scope=&#8221;col&#8221; instead. Here&#8217;s the code:</p>
<pre class="brush: csharp;">
    public class TableHeaderCellAdapter : WebControlAdapter
    {
        protected override void RenderBeginTag(HtmlTextWriter writer)
        {
            TableHeaderCell th = (TableHeaderCell) this.Control;

            if (th.Scope == TableHeaderScope.Column)
            {
                th.Scope = TableHeaderScope.NotSet;
                th.Attributes[&quot;scope&quot;] = &quot;col&quot;;
            }

            base.RenderBeginTag(writer);
        }
    }
</pre>
<p>To associate the control adapter class with the TableHeaderCell control, add a browser definition file to the App_Browsers folder:</p>
<pre class="brush: xml;">
    &lt;!-- file: ~/App_Browsers/ControlAdapters.browser --&gt;
    &lt;browsers&gt;
        &lt;browser refID=&quot;Default&quot;&gt;
            &lt;controlAdapters&gt;
                &lt;adapter
                  controlType=&quot;System.Web.UI.WebControls.TableHeaderCell&quot;
                  adapterType=&quot;TableHeaderCellAdapter&quot; /&gt;
            &lt;/controlAdapters&gt;
        &lt;/browser&gt;
    &lt;/browsers&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/tableheaderscope-column-and-html-standards-compliance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring IIS7 for ASP.NET on Windows Vista</title>
		<link>http://chrisfulstow.com/configuring-iis7-for-asp-net-on-windows-vista/</link>
		<comments>http://chrisfulstow.com/configuring-iis7-for-asp-net-on-windows-vista/#comments</comments>
		<pubDate>Fri, 05 Feb 2010 01:13:11 +0000</pubDate>
		<dc:creator>Chris Fulstow</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://chrisfulstow.com/?p=266</guid>
		<description><![CDATA[As part of Microsoft&#8217;s ongoing Trustworthy Computing initiative, Vista takes the secure by default principle more seriously than previous versions of Windows. Consequently, many features aren&#8217;t installed by default, one of which is IIS 7. So, to install IIS go to:
Control Panel &#8211; Programs &#8211; Turn Windows features on or off
Then find the Intenet Information <a href="http://chrisfulstow.com/configuring-iis7-for-asp-net-on-windows-vista/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>As part of Microsoft&#8217;s ongoing <a href="http://www.microsoft.com/mscorp/twc/">Trustworthy Computing</a> initiative, Vista takes the <a href="http://en.wikipedia.org/wiki/Secure_by_default">secure by default</a> principle more seriously than previous versions of Windows. Consequently, many features aren&#8217;t installed by default, one of which is IIS 7. So, to install IIS go to:</p>
<p><strong>Control Panel &#8211; Programs &#8211; Turn Windows features on or off</strong></p>
<p>Then find the <em>Intenet Information Services</em> section and add everything you need, including <em>ASP.NET</em>.</p>
<p><a href="http://chrisfulstow.com/wp-content/uploads/2010/02/aspnet-win-features.png"><img class="alignnone size-full wp-image-267" title="ASP.NET Windows Features" src="http://chrisfulstow.com/wp-content/uploads/2010/02/aspnet-win-features.png" alt="ASP.NET Windows Features" width="429" height="455" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://chrisfulstow.com/configuring-iis7-for-asp-net-on-windows-vista/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
