<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>The Blog of Many Hats - The Geek</title>
    <link>http://blog.slatner.com/</link>
    <description>.NET, Cigars, Food. You know, the good stuff.</description>
    <language>en-us</language>
    <copyright>Bryan E. Slatner</copyright>
    <lastBuildDate>Wed, 20 Jan 2010 05:50:08 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>bryan@slatner.com</managingEditor>
    <webMaster>bryan@slatner.com</webMaster>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=52d379b4-4027-4bba-8a25-0a0e9c8049bc</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,52d379b4-4027-4bba-8a25-0a0e9c8049bc.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,52d379b4-4027-4bba-8a25-0a0e9c8049bc.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=52d379b4-4027-4bba-8a25-0a0e9c8049bc</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It’s fairly common to use hidden form fields to store a value that gets posted back
to your controller for the purposes of establishing context.
</p>
        <p>
For example, on an edit form, you might render a hidden field containing the ID of
the entity you’re editing. This is actually preferable to using route values because
it’s much easier to tamper with those than it is to tamper with form data.
</p>
        <p>
That said…it’s still pretty darn easy to tamper with form data. If you’re using <a href="http://getfirebug.com/" target="_blank">FireBug</a>,
you can view the current page’s DOM and fiddle with any value you please. This can
be catastrophically bad if, for example, an attacker views a form to edit an entity
they have access to, and then changes the entity ID field to the ID of an entity they
don’t have access to. Granted, your validation code should handle that case, but when
it comes to attacks, an ounce of prevention is worth a pound of cure.
</p>
        <p>
So, how to prevent an attacker from tampering with our hidden fields?
</p>
        <p>
One solution is to create a secure hash of the field in question and render that to
the client as well. Then, on postback, validate that the hash of the incoming value
matches the original hash. Here’s an example of the HTML for that:
</p>
        <pre class="brush: xml;">&lt;input id="productId" name="productId" type="hidden" value="1" /&gt;
&lt;input id="productId_sha1" name="productId_sha1" type="hidden" value="vMrgoclb/K+6EQ+6FK9K69V2vkQ=" /&gt;&lt;</pre>
        <p>
The second hidden field is the SHA1 hash of the productId value 1, plus a secret value
that makes tampering with the hash impossible.
</p>
        <p>
I’ve written an HTML helper that facilitates creating these hash fields. Here’s how
it’s used:
</p>
        <pre class="brush: xml;">&lt;% using(Html.BeginForm()) { %&gt;
    &lt;%=Html.SecuredHiddenField("productId", 1) %&gt;
    &lt;fieldset&gt;  
        &lt;p&gt;&lt;label for="Name"&gt;Product Name:&lt;/label&gt; &lt;%=Html.TextBox("productName") %&gt;&lt;/p&gt;
        &lt;button name="save" value="with"&gt;Save Product&lt;/button&gt;
    &lt;/fieldset&gt;
&lt;% } %&gt;</pre>
        <p>
And here’s the code for the HTML helper:
</p>
        <pre class="brush: csharp;">public static class SecuredValueHtmlHelper
{
    public static string SecuredHiddenField(this HtmlHelper htmlHelper, string name, object value)
    {
        var html = new StringBuilder();
        html.Append(htmlHelper.Hidden(name, value));
        html.Append(GetHashFieldHtml(htmlHelper, name, GetValueAsString(value)));
        return html.ToString();
    }

    public static string HashField(this HtmlHelper htmlHelper, string name, object value)
    {
        return GetHashFieldHtml(htmlHelper, name, GetValueAsString(value));
    }

    public static string MultipleFieldHashField(this HtmlHelper htmlHelper, string name, IEnumerable values)
    {
        var valueToHash = new StringBuilder();
        foreach (var v in values)
        {
            valueToHash.Append(v);
        }

        return HashField(htmlHelper, name, valueToHash);
    }

    private static string GetValueAsString(object value)
    {
        return Convert.ToString(value, CultureInfo.CurrentCulture);
    }

    private static string GetHashFieldHtml(HtmlHelper htmlHelper, string name, string value)
    {
        return htmlHelper.Hidden(SecuredValueFieldNameComputer.GetSecuredValueFieldName(name),
                                 SecuredValueHashComputer.GetHash(value));
    }
}</pre>
        <p>
The HTML helper uses a class called SecuredValueHashComputer to compute the SHA1 hash.
I’ve written it so that you can plug in any hash computer that you want (MD5, or say
SHA512 for the really paranoid):
</p>
        <pre class="brush: csharp;">public static class SecuredValueHashComputer
{
    public static string Secret { get; set; }
    public static IHashComputer HashComputer { get; set; }

    static SecuredValueHashComputer()
    {
        Secret = "zomg!";
        HashComputer = new SHA1HashComputer();
    }

    public static string GetHash(string value)
    {
        return HashComputer.GetBase64HashString(value, Secret);
    }
}</pre>
        <p>
In an ideal world, you’d load the value for “Secret” from your Web.config (preferably
from an encrypted section) and use an IoC container to instantiate the IHashComputer.
</p>
        <p>
Finally, validate the data like so:
</p>
        <pre class="brush: csharp;">[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int productId, string productName, string save, FormCollection formValues)
{
    if (save == "with")
    {
        SecuredValueValidator.ValidateValue(formValues, "productId");
    }

    ViewData["message"] = string.Format("Product ID {0} was saved!", productId);

    return View();
}</pre>
        <p>
The complete source code is available at <a href="http://blog.slatner.com/downloads/SecuredFormExample.zip">http://blog.slatner.com/downloads/SecuredFormExample.zip</a>.
</p>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=52d379b4-4027-4bba-8a25-0a0e9c8049bc" />
      </body>
      <title>Securing Form Values in ASP.NET MVC</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,52d379b4-4027-4bba-8a25-0a0e9c8049bc.aspx</guid>
      <link>http://blog.slatner.com/2010/01/20/SecuringFormValuesInASPNETMVC.aspx</link>
      <pubDate>Wed, 20 Jan 2010 05:50:08 GMT</pubDate>
      <description>&lt;p&gt;
It’s fairly common to use hidden form fields to store a value that gets posted back
to your controller for the purposes of establishing context.
&lt;/p&gt;
&lt;p&gt;
For example, on an edit form, you might render a hidden field containing the ID of
the entity you’re editing. This is actually preferable to using route values because
it’s much easier to tamper with those than it is to tamper with form data.
&lt;/p&gt;
&lt;p&gt;
That said…it’s still pretty darn easy to tamper with form data. If you’re using &lt;a href="http://getfirebug.com/" target="_blank"&gt;FireBug&lt;/a&gt;,
you can view the current page’s DOM and fiddle with any value you please. This can
be catastrophically bad if, for example, an attacker views a form to edit an entity
they have access to, and then changes the entity ID field to the ID of an entity they
don’t have access to. Granted, your validation code should handle that case, but when
it comes to attacks, an ounce of prevention is worth a pound of cure.
&lt;/p&gt;
&lt;p&gt;
So, how to prevent an attacker from tampering with our hidden fields?
&lt;/p&gt;
&lt;p&gt;
One solution is to create a secure hash of the field in question and render that to
the client as well. Then, on postback, validate that the hash of the incoming value
matches the original hash. Here’s an example of the HTML for that:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;input id=&amp;quot;productId&amp;quot; name=&amp;quot;productId&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;1&amp;quot; /&amp;gt;
&amp;lt;input id=&amp;quot;productId_sha1&amp;quot; name=&amp;quot;productId_sha1&amp;quot; type=&amp;quot;hidden&amp;quot; value=&amp;quot;vMrgoclb/K+6EQ+6FK9K69V2vkQ=&amp;quot; /&amp;gt;&amp;lt;&lt;/pre&gt;
&lt;p&gt;
The second hidden field is the SHA1 hash of the productId value 1, plus a secret value
that makes tampering with the hash impossible.
&lt;/p&gt;
&lt;p&gt;
I’ve written an HTML helper that facilitates creating these hash fields. Here’s how
it’s used:
&lt;/p&gt;
&lt;pre class="brush: xml;"&gt;&amp;lt;% using(Html.BeginForm()) { %&amp;gt;
    &amp;lt;%=Html.SecuredHiddenField(&amp;quot;productId&amp;quot;, 1) %&amp;gt;
    &amp;lt;fieldset&amp;gt;  
        &amp;lt;p&amp;gt;&amp;lt;label for=&amp;quot;Name&amp;quot;&amp;gt;Product Name:&amp;lt;/label&amp;gt; &amp;lt;%=Html.TextBox(&amp;quot;productName&amp;quot;) %&amp;gt;&amp;lt;/p&amp;gt;
        &amp;lt;button name=&amp;quot;save&amp;quot; value=&amp;quot;with&amp;quot;&amp;gt;Save Product&amp;lt;/button&amp;gt;
    &amp;lt;/fieldset&amp;gt;
&amp;lt;% } %&amp;gt;&lt;/pre&gt;
&lt;p&gt;
And here’s the code for the HTML helper:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static class SecuredValueHtmlHelper
{
    public static string SecuredHiddenField(this HtmlHelper htmlHelper, string name, object value)
    {
        var html = new StringBuilder();
        html.Append(htmlHelper.Hidden(name, value));
        html.Append(GetHashFieldHtml(htmlHelper, name, GetValueAsString(value)));
        return html.ToString();
    }

    public static string HashField(this HtmlHelper htmlHelper, string name, object value)
    {
        return GetHashFieldHtml(htmlHelper, name, GetValueAsString(value));
    }

    public static string MultipleFieldHashField(this HtmlHelper htmlHelper, string name, IEnumerable values)
    {
        var valueToHash = new StringBuilder();
        foreach (var v in values)
        {
            valueToHash.Append(v);
        }

        return HashField(htmlHelper, name, valueToHash);
    }

    private static string GetValueAsString(object value)
    {
        return Convert.ToString(value, CultureInfo.CurrentCulture);
    }

    private static string GetHashFieldHtml(HtmlHelper htmlHelper, string name, string value)
    {
        return htmlHelper.Hidden(SecuredValueFieldNameComputer.GetSecuredValueFieldName(name),
                                 SecuredValueHashComputer.GetHash(value));
    }
}&lt;/pre&gt;
&lt;p&gt;
The HTML helper uses a class called SecuredValueHashComputer to compute the SHA1 hash.
I’ve written it so that you can plug in any hash computer that you want (MD5, or say
SHA512 for the really paranoid):
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;public static class SecuredValueHashComputer
{
    public static string Secret { get; set; }
    public static IHashComputer HashComputer { get; set; }

    static SecuredValueHashComputer()
    {
        Secret = &amp;quot;zomg!&amp;quot;;
        HashComputer = new SHA1HashComputer();
    }

    public static string GetHash(string value)
    {
        return HashComputer.GetBase64HashString(value, Secret);
    }
}&lt;/pre&gt;
&lt;p&gt;
In an ideal world, you’d load the value for “Secret” from your Web.config (preferably
from an encrypted section) and use an IoC container to instantiate the IHashComputer.
&lt;/p&gt;
&lt;p&gt;
Finally, validate the data like so:
&lt;/p&gt;
&lt;pre class="brush: csharp;"&gt;[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(int productId, string productName, string save, FormCollection formValues)
{
    if (save == &amp;quot;with&amp;quot;)
    {
        SecuredValueValidator.ValidateValue(formValues, &amp;quot;productId&amp;quot;);
    }

    ViewData[&amp;quot;message&amp;quot;] = string.Format(&amp;quot;Product ID {0} was saved!&amp;quot;, productId);

    return View();
}&lt;/pre&gt;
&lt;p&gt;
The complete source code is available at &lt;a href="http://blog.slatner.com/downloads/SecuredFormExample.zip"&gt;http://blog.slatner.com/downloads/SecuredFormExample.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=52d379b4-4027-4bba-8a25-0a0e9c8049bc" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,52d379b4-4027-4bba-8a25-0a0e9c8049bc.aspx</comments>
      <category>The Geek</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=454168c0-46ab-4e67-9b3b-e2e1860f502b</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,454168c0-46ab-4e67-9b3b-e2e1860f502b.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,454168c0-46ab-4e67-9b3b-e2e1860f502b.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=454168c0-46ab-4e67-9b3b-e2e1860f502b</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Fought for an hour tonight to get syntax highlighting working in my preferred dasBlog
theme. Didn't happen. Finally switched themes and everything worked right.
</p>
        <p>
My thanks to <a href="http://alexgorbatchev.com/">Alex Gorbatchev</a> for such an
awesome <a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter">tool</a>.<img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=454168c0-46ab-4e67-9b3b-e2e1860f502b" /></p>
      </body>
      <title>Syntax Highlighting</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,454168c0-46ab-4e67-9b3b-e2e1860f502b.aspx</guid>
      <link>http://blog.slatner.com/2010/01/20/SyntaxHighlighting.aspx</link>
      <pubDate>Wed, 20 Jan 2010 05:18:10 GMT</pubDate>
      <description>&lt;p&gt;
Fought for an hour tonight to get syntax highlighting working in my preferred dasBlog
theme. Didn't happen. Finally switched themes and everything worked right.
&lt;/p&gt;
&lt;p&gt;
My thanks to &lt;a href="http://alexgorbatchev.com/"&gt;Alex Gorbatchev&lt;/a&gt; for such an
awesome &lt;a href="http://alexgorbatchev.com/wiki/SyntaxHighlighter"&gt;tool&lt;/a&gt;.&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=454168c0-46ab-4e67-9b3b-e2e1860f502b" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,454168c0-46ab-4e67-9b3b-e2e1860f502b.aspx</comments>
      <category>The Geek</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=8447dc05-9034-496b-9e63-c5863e1c8905</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,8447dc05-9034-496b-9e63-c5863e1c8905.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,8447dc05-9034-496b-9e63-c5863e1c8905.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=8447dc05-9034-496b-9e63-c5863e1c8905</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ever since I heard about the concept of "code kata", I've been practicing them every
day.
</p>
        <p>
If you hadn't heard, code kata are lot like those in martial arts. They are an exercise
wherein you make the same decisions over and over again so that you are more likely
to make those same decisions again when under stress. Since TDD is a somewhat rigid
process where the same rules are followed over and over again it lends itself to this
concept of "kata".
</p>
        <p>
There are a couple of kata that I do. First, the "calculator kata" (thanks <a href="http://www.21apps.com/agile/tdd-kata-by-example-video/">Andrew
Woodward</a>), where you create a class with a method that sums all of that numbers
in a comma delimited string.
</p>
        <p>
Second, and more fun, is a kata where you write a method to return a list of all of
a number's prime factors. I first learned about this kata from <a href="http://blog.objectmentor.com/">Uncle
Bob Martin</a>. A few days ago he mentioned on Twitter that he was trying to get a
screencast of a "flawless" version of this kata. After about 30 attempts, I did not
achieve "flawless", but I think I achieved "pretty good".
</p>
        <p>
This first video shows the primary kata exercise. Using TDD, I steadily create a method
called Generate that lists the prime factors for an input integer. I also use Resharper
and its templating and refactoring features to make this process easier. As an aside,
if you are not presently using something like <a href="http://www.jetbrains.com/resharper/">Resharper</a> or <a href="http://msdn.microsoft.com/en-us/vcsharp/dd218053.aspx">CodeRush</a> to
help you as you code, you are definitely doing things the hard way.
</p>
        <p>
In the video, I try to rigidly adhere to the TDD method:
</p>
        <ol>
          <li>
Write a test first</li>
          <li>
Watch it fail</li>
          <li>
Write just enough code to make it pass</li>
          <li>
Verify the test passes</li>
          <li>
Refactor</li>
        </ol>
        <p>
On that note, I know it annoys people to no end when I hard-code return values when
I <b>know I'll be eliminating that code very shortly</b>. But it's neat to watch how
the algorithm transforms over the course of the kata, and you wouldn't see it if you
didn't follow the steps rigidly.
</p>
        <div class="screencast">
          <object id="csSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version==8" height="823" width="1024">
            <param name="src" value="/screencasts/PrimesFactorsKata/PrimesFactorsKata_controller.swf#" />
            <param name="bgcolor" value="FFFFFF" />
            <param name="quality" value="best" />
            <param name="allowScriptAccess" value="always" />
            <param name="flashVars" value="csConfigFile=/screencasts/PrimesFactorsKata/PrimesFactorsKata_config.xml&amp;csColor=FFFFFF;autoplay=false;autoStart=false" />
            <embed name="csSWF" src="/screencasts/PrimesFactorsKata/PrimesFactorsKata_controller.swf" bgcolor="FFFFFF" quality="best" allowscriptaccess="always" flashvars="csConfigFile=/screencasts/PrimesFactorsKata/PrimesFactorsKata_config.xml&amp;csColor=FFFFFF;autoplay=false;autoStart=false" pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" height="823" width="1024">
            </embed>
          </object>
        </div>
        <p>
This second video is not part of the kata, but it's meant to show two things:
</p>
        <ul>
          <li>
Refactoring the code and using your existing tests to validate that you haven't broken
anything. I call this the "real coder" refactoring since it replaces the easy-to-read
while loops with not-so-easy-to-read for loops.</li>
          <li>
The use of MbUnit's "Row" tests that we can use the same test code to validate multiple
inputs to the validator.</li>
        </ul>
        <div class="screencast">
          <object id="csSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version==8" height="823" width="1024">
            <param name="src" value="/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_controller.swf#" />
            <param name="bgcolor" value="FFFFFF" />
            <param name="quality" value="best" />
            <param name="allowScriptAccess" value="always" />
            <param name="flashVars" value="csConfigFile=/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_config.xml&amp;csColor=FFFFFF;autoPlay=false;autoStart=false" />
            <embed name="csSWF" src="/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_controller.swf" bgcolor="FFFFFF" quality="best" allowscriptaccess="always" flashvars="csConfigFile=/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_config.xml&amp;csColor=FFFFFF;autoPlay=false;autoStart=false" pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" height="823" width="1024">
            </embed>
          </object>
        </div>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=8447dc05-9034-496b-9e63-c5863e1c8905" />
      </body>
      <title>Prime Factors Kata in C#</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,8447dc05-9034-496b-9e63-c5863e1c8905.aspx</guid>
      <link>http://blog.slatner.com/2009/11/11/PrimeFactorsKataInC.aspx</link>
      <pubDate>Wed, 11 Nov 2009 16:56:07 GMT</pubDate>
      <description>&lt;p&gt;
Ever since I heard about the concept of "code kata", I've been practicing them every
day.
&lt;/p&gt;
&lt;p&gt;
If you hadn't heard, code kata are lot like those in martial arts. They are an exercise
wherein you make the same decisions over and over again so that you are more likely
to make those same decisions again when under stress. Since TDD is a somewhat rigid
process where the same rules are followed over and over again it lends itself to this
concept of "kata".
&lt;/p&gt;
&lt;p&gt;
There are a couple of kata that I do. First, the "calculator kata" (thanks &lt;a href="http://www.21apps.com/agile/tdd-kata-by-example-video/"&gt;Andrew
Woodward&lt;/a&gt;), where you create a class with a method that sums all of that numbers
in a comma delimited string.
&lt;/p&gt;
&lt;p&gt;
Second, and more fun, is a kata where you write a method to return a list of all of
a number's prime factors. I first learned about this kata from &lt;a href="http://blog.objectmentor.com/"&gt;Uncle
Bob Martin&lt;/a&gt;. A few days ago he mentioned on Twitter that he was trying to get a
screencast of a "flawless" version of this kata. After about 30 attempts, I did not
achieve "flawless", but I think I achieved "pretty good".
&lt;/p&gt;
&lt;p&gt;
This first video shows the primary kata exercise. Using TDD, I steadily create a method
called Generate that lists the prime factors for an input integer. I also use Resharper
and its templating and refactoring features to make this process easier. As an aside,
if you are not presently using something like &lt;a href="http://www.jetbrains.com/resharper/"&gt;Resharper&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/vcsharp/dd218053.aspx"&gt;CodeRush&lt;/a&gt; to
help you as you code, you are definitely doing things the hard way.
&lt;/p&gt;
&lt;p&gt;
In the video, I try to rigidly adhere to the TDD method:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
Write a test first&lt;/li&gt;
&lt;li&gt;
Watch it fail&lt;/li&gt;
&lt;li&gt;
Write just enough code to make it pass&lt;/li&gt;
&lt;li&gt;
Verify the test passes&lt;/li&gt;
&lt;li&gt;
Refactor&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
On that note, I know it annoys people to no end when I hard-code return values when
I &lt;b&gt;know I'll be eliminating that code very shortly&lt;/b&gt;. But it's neat to watch how
the algorithm transforms over the course of the kata, and you wouldn't see it if you
didn't follow the steps rigidly.
&lt;/p&gt;
&lt;div class="screencast"&gt;
&lt;object id="csSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version==8" height="823" width="1024"&gt;
&lt;param name="src" value="/screencasts/PrimesFactorsKata/PrimesFactorsKata_controller.swf#"&gt;
&lt;param name="bgcolor" value="FFFFFF"&gt;
&lt;param name="quality" value="best"&gt;
&lt;param name="allowScriptAccess" value="always"&gt;
&lt;param name="flashVars" value="csConfigFile=/screencasts/PrimesFactorsKata/PrimesFactorsKata_config.xml&amp;amp;csColor=FFFFFF;autoplay=false;autoStart=false"&gt;
&lt;embed name="csSWF" src="/screencasts/PrimesFactorsKata/PrimesFactorsKata_controller.swf" bgcolor="FFFFFF" quality="best" allowscriptaccess="always" flashvars="csConfigFile=/screencasts/PrimesFactorsKata/PrimesFactorsKata_config.xml&amp;amp;csColor=FFFFFF;autoplay=false;autoStart=false" pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" height="823" width="1024"&gt; 
&lt;/object&gt;
&lt;/div&gt;
&lt;p&gt;
This second video is not part of the kata, but it's meant to show two things:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Refactoring the code and using your existing tests to validate that you haven't broken
anything. I call this the "real coder" refactoring since it replaces the easy-to-read
while loops with not-so-easy-to-read for loops.&lt;/li&gt;
&lt;li&gt;
The use of MbUnit's "Row" tests that we can use the same test code to validate multiple
inputs to the validator.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="screencast"&gt;
&lt;object id="csSWF" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version==8" height="823" width="1024"&gt;
&lt;param name="src" value="/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_controller.swf#"&gt;
&lt;param name="bgcolor" value="FFFFFF"&gt;
&lt;param name="quality" value="best"&gt;
&lt;param name="allowScriptAccess" value="always"&gt;
&lt;param name="flashVars" value="csConfigFile=/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_config.xml&amp;amp;csColor=FFFFFF;autoPlay=false;autoStart=false"&gt;
&lt;embed name="csSWF" src="/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_controller.swf" bgcolor="FFFFFF" quality="best" allowscriptaccess="always" flashvars="csConfigFile=/screencasts/PrimeFactorsRefactorAndMoreTests/PrimeFactorsRefactorAndMoreTests_config.xml&amp;amp;csColor=FFFFFF;autoPlay=false;autoStart=false" pluginspage="http://www.adobe.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" height="823" width="1024"&gt; 
&lt;/object&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=8447dc05-9034-496b-9e63-c5863e1c8905" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,8447dc05-9034-496b-9e63-c5863e1c8905.aspx</comments>
      <category>The Geek</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=64769cf4-a113-43fe-aa08-0be0f4026a52</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,64769cf4-a113-43fe-aa08-0be0f4026a52.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,64769cf4-a113-43fe-aa08-0be0f4026a52.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=64769cf4-a113-43fe-aa08-0be0f4026a52</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.waiterrant.net/" target="new">Waiter Rant</a> has been out of
commission for several days now.
</p>
        <p>
For anyone wondering what happened, the good folks at <a href="http://www.soundque.com/" target="_new">SoundQue</a> --
who host his site -- have confirmed that the WordPress software Waiter uses was hacked.
</p>
        <p>
I suspected a hacker when, on the first day I began to get suspicious, I looked at
the HTML source and saw that there was a hidden &lt;iframe&gt; tag that was downloading
content from http://www.allddos.biz. None of that sounded good to me.
</p>
        <p>
In any event, I'm assured that Waiter will be back on the air in a couple of days.
</p>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=64769cf4-a113-43fe-aa08-0be0f4026a52" />
      </body>
      <title>Whither Waiter?</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,64769cf4-a113-43fe-aa08-0be0f4026a52.aspx</guid>
      <link>http://blog.slatner.com/2007/05/24/WhitherWaiter.aspx</link>
      <pubDate>Thu, 24 May 2007 19:19:45 GMT</pubDate>
      <description>&lt;p&gt;
&lt;a href="http://www.waiterrant.net/" target="new"&gt;Waiter Rant&lt;/a&gt; has been out of
commission for several days now.
&lt;/p&gt;
&lt;p&gt;
For anyone wondering what happened, the good folks at &lt;a href="http://www.soundque.com/" target="_new"&gt;SoundQue&lt;/a&gt; --
who host his site -- have confirmed that the WordPress software Waiter uses was hacked.
&lt;/p&gt;
&lt;p&gt;
I suspected a hacker when, on the first day I began to get suspicious, I looked at
the HTML source and saw that there was a hidden &amp;lt;iframe&amp;gt; tag that was downloading
content from http://www.allddos.biz. None of that sounded good to me.
&lt;/p&gt;
&lt;p&gt;
In any event, I'm assured that Waiter will be back on the air in a couple of days.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=64769cf4-a113-43fe-aa08-0be0f4026a52" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,64769cf4-a113-43fe-aa08-0be0f4026a52.aspx</comments>
      <category>Everything Else</category>
      <category>The Geek</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=28fcb98f-66a4-454a-9d2c-3139b682708f</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,28fcb98f-66a4-454a-9d2c-3139b682708f.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,28fcb98f-66a4-454a-9d2c-3139b682708f.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=28fcb98f-66a4-454a-9d2c-3139b682708f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Came to the computer, needing to print. Hit print button. No joy. Look at the display.
No display. No flashy little lights on the console. All symptoms point to loss of
power.
</p>
        <p>
Can't be loss of power. Printer's had power non-stop for almost 2 years. It's even
on the UPS.
</p>
        <p>
Look around the room. Computer on. Lights on. House has power. But printer acts like
it has no power.
</p>
        <p>
But it <b>can't</b> be power loss. Printer's had power non-stop for almost 2 years.
</p>
        <p>
Scratch head. Apply Occam's razor. Simplest answer is that printer has no power. Sigh.
It's pointless and time wasting, but try anyway. Check power connector on back of
printer. It's snug. Follow cable. Follow cable over bookcase. Follow cable under chair
cushion. Finally get to wall.
</p>
        <p>
          <i>
            <b>Fuck</b>
          </i>. Printer <b>not</b> on UPS. Printer <b>not</b> plugged in. Wife
unplugged printer to charge cell phone. Why cellphone charger needs uninterruptable
power? Question for another day.<br /></p>
        <p>
Sigh. "That's why we ask stupid troubleshooting questions."
</p>
        <p>
Dammit.
</p>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=28fcb98f-66a4-454a-9d2c-3139b682708f" />
      </body>
      <title>Why We Ask Stupid Troubleshooting Questions</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,28fcb98f-66a4-454a-9d2c-3139b682708f.aspx</guid>
      <link>http://blog.slatner.com/2007/02/24/WhyWeAskStupidTroubleshootingQuestions.aspx</link>
      <pubDate>Sat, 24 Feb 2007 14:01:25 GMT</pubDate>
      <description>&lt;p&gt;
Came to the computer, needing to print. Hit print button. No joy. Look at the display.
No display. No flashy little lights on the console. All symptoms point to loss of
power.
&lt;/p&gt;
&lt;p&gt;
Can't be loss of power. Printer's had power non-stop for almost 2 years. It's even
on the UPS.
&lt;/p&gt;
&lt;p&gt;
Look around the room. Computer on. Lights on. House has power. But printer acts like
it has no power.
&lt;/p&gt;
&lt;p&gt;
But it &lt;b&gt;can't&lt;/b&gt; be power loss. Printer's had power non-stop for almost 2 years.
&lt;/p&gt;
&lt;p&gt;
Scratch head. Apply Occam's razor. Simplest answer is that printer has no power. Sigh.
It's pointless and time wasting, but try anyway. Check power connector on back of
printer. It's snug. Follow cable. Follow cable over bookcase. Follow cable under chair
cushion. Finally get to wall.
&lt;/p&gt;
&lt;p&gt;
&lt;i&gt;&lt;b&gt;Fuck&lt;/b&gt;&lt;/i&gt;. Printer &lt;b&gt;not&lt;/b&gt; on UPS. Printer &lt;b&gt;not&lt;/b&gt; plugged in. Wife
unplugged printer to charge cell phone. Why cellphone charger needs uninterruptable
power? Question for another day.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
Sigh. "That's why we ask stupid troubleshooting questions."
&lt;/p&gt;
&lt;p&gt;
Dammit.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=28fcb98f-66a4-454a-9d2c-3139b682708f" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,28fcb98f-66a4-454a-9d2c-3139b682708f.aspx</comments>
      <category>The Geek</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=621b37d2-2a6b-427f-9696-cc71c1d4e8e1</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,621b37d2-2a6b-427f-9696-cc71c1d4e8e1.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,621b37d2-2a6b-427f-9696-cc71c1d4e8e1.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=621b37d2-2a6b-427f-9696-cc71c1d4e8e1</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The folks over at <a href="http://www.drivl.com/" target="_new">Drivl</a> have a <b>very</b> funny
blog about what code <b>doesn't</b> do. As opposed to what movies tell us it does
</p>
        <p>
          <a href="http://www.drivl.com/posts/view/494" target="_new">Check it out</a>.
</p>
        <p>
Oh, and while we're dispelling code and coder stereotypes, I'll toss in my two cents:
real programmers abhor animation of any kind. Yes, games are animated. And graphics
designers and movie makers need to deal with animation. But we do not build our tools
to contain needless, stupid animation. Mostly, we just want to get our work done and
animation just slows us down. So when you see a movie guy click a button, or press
a key, and a remarkably complex piece of animation plays to indicate that work is
being done...yeah, that's bullshit.
</p>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=621b37d2-2a6b-427f-9696-cc71c1d4e8e1" />
      </body>
      <title>What Code Doesn't Do</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,621b37d2-2a6b-427f-9696-cc71c1d4e8e1.aspx</guid>
      <link>http://blog.slatner.com/2007/01/30/WhatCodeDoesntDo.aspx</link>
      <pubDate>Tue, 30 Jan 2007 17:46:36 GMT</pubDate>
      <description>&lt;p&gt;
The folks over at &lt;a href="http://www.drivl.com/" target=_new&gt;Drivl&lt;/a&gt; have a &lt;b&gt;very&lt;/b&gt; funny
blog about what code &lt;b&gt;doesn't&lt;/b&gt; do. As opposed to what movies tell us it does
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.drivl.com/posts/view/494" target=_new&gt;Check it out&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Oh, and while we're dispelling code and coder stereotypes, I'll toss in my two cents:
real programmers abhor animation of any kind. Yes, games are animated. And graphics
designers and movie makers need to deal with animation. But we do not build our tools
to contain needless, stupid animation. Mostly, we just want to get our work done and
animation just slows us down. So when you see a movie guy click a button, or press
a key, and a remarkably complex piece of animation plays to indicate that work is
being done...yeah, that's bullshit.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=621b37d2-2a6b-427f-9696-cc71c1d4e8e1" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,621b37d2-2a6b-427f-9696-cc71c1d4e8e1.aspx</comments>
      <category>The Geek</category>
      <category>The Jester</category>
    </item>
    <item>
      <trackback:ping>http://blog.slatner.com/Trackback.aspx?guid=44d05bd2-3184-4656-9aac-0da95dac4742</trackback:ping>
      <pingback:server>http://blog.slatner.com/pingback.aspx</pingback:server>
      <pingback:target>http://blog.slatner.com/PermaLink,guid,44d05bd2-3184-4656-9aac-0da95dac4742.aspx</pingback:target>
      <dc:creator>Bryan Slatner</dc:creator>
      <wfw:comment>http://blog.slatner.com/CommentView,guid,44d05bd2-3184-4656-9aac-0da95dac4742.aspx</wfw:comment>
      <wfw:commentRss>http://blog.slatner.com/SyndicationService.asmx/GetEntryCommentsRss?guid=44d05bd2-3184-4656-9aac-0da95dac4742</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Mike from <a href="http://barelylegalblog.blogspot.com/" target="_new">Barely Legal</a> has
a new blog called <a href="http://in-it-but-not-of-it.blogspot.com/" target="_new">In
It But Not Of It</a>.
</p>
        <p>
Today, <a href="http://in-it-but-not-of-it.blogspot.com/2007/01/goodbye-old-friend.html">he
writes</a> a post that only a man could write. It's about the death of a dear piece
of consumer electronics.
</p>
        <p>
I say it's a Post Only a Man Could Write because, really, women don't anthropomorphize
things the way us men do. If a woman's favorite hairdryer breaks, she might be sad
about it, but you'll never hear her say something like "Oh, Doris! &lt;sob!&gt; You
were so good to me!"
</p>
        <p>
But when my 1980 Honda Accord died, I said "Goodbye, Hubert!" and gave a little sniff
when the tow truck hauled him away.
</p>
        <img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=44d05bd2-3184-4656-9aac-0da95dac4742" />
      </body>
      <title>A Post Only a Man Could Write</title>
      <guid isPermaLink="false">http://blog.slatner.com/PermaLink,guid,44d05bd2-3184-4656-9aac-0da95dac4742.aspx</guid>
      <link>http://blog.slatner.com/2007/01/17/APostOnlyAManCouldWrite.aspx</link>
      <pubDate>Wed, 17 Jan 2007 19:53:07 GMT</pubDate>
      <description>&lt;p&gt;
Mike from &lt;a href="http://barelylegalblog.blogspot.com/" target="_new"&gt;Barely Legal&lt;/a&gt; has
a new blog called &lt;a href="http://in-it-but-not-of-it.blogspot.com/" target="_new"&gt;In
It But Not Of It&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Today, &lt;a href="http://in-it-but-not-of-it.blogspot.com/2007/01/goodbye-old-friend.html"&gt;he
writes&lt;/a&gt; a post that only a man could write. It's about the death of a dear piece
of consumer electronics.
&lt;/p&gt;
&lt;p&gt;
I say it's a Post Only a Man Could Write because, really, women don't anthropomorphize
things the way us men do. If a woman's favorite hairdryer breaks, she might be sad
about it, but you'll never hear her say something like "Oh, Doris! &amp;lt;sob!&amp;gt; You
were so good to me!"
&lt;/p&gt;
&lt;p&gt;
But when my 1980 Honda Accord died, I said "Goodbye, Hubert!" and gave a little sniff
when the tow truck hauled him away.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.slatner.com/aggbug.ashx?id=44d05bd2-3184-4656-9aac-0da95dac4742" /&gt;</description>
      <comments>http://blog.slatner.com/CommentView,guid,44d05bd2-3184-4656-9aac-0da95dac4742.aspx</comments>
      <category>The Geek</category>
    </item>
  </channel>
</rss>