<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>The Blog of Josh Stodola</title>
    <description>Technical blog related to web development with ASP.NET and Javascript, and a few other things.</description>
    <link>http://blog.josh420.com/</link>
    <copyright>Copyright 2009 Josh Stodola - All rights reserved.</copyright>
    <generator>Argotic</generator>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <language>EN</language>
    <lastBuildDate>Wed, 11 Nov 2009 17:32:57 -0600</lastBuildDate>
    <managingEditor>Josh Stodola - josh420@josh420.com</managingEditor>
    <pubDate>Wed, 11 Nov 2009 17:32:57 -0600</pubDate>
    <webMaster>josh420@josh420.com</webMaster>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Sorting a Generic List Dynamically in VB.NET</title>
      <description>&lt;p&gt;In a recent post, &lt;a href="http://blog.josh420.com/archives/2009/01/creating-an-excel-spreadsheet-from-generic-list-in-vbnet.aspx" target="_blank" title="Josh Stodola - Convert a Generic List to Excel Spreadsheet"&gt;I talked about generic lists&lt;/a&gt; and how we have been using them at work as a replacement for the DataTable class. For the most part, it has been a real pleasure getting rid of DataTable, but I will admit that there are certain situations in which a DataTable is easier to code for. This is primarily because DataTables are mature and robust, and several helper classes already exist in the .NET framework to process them. The Fill function for the SqlDataAdapter, for example,&amp;nbsp;will automatically load a DataTable with the result of an SQL command for you, which is extremely convenient. There are other classes such as DataView that make manipulative tasks (like sorting and filtering) a piece of cake. For instance, say you have a DataTable populated with about 500 rows and you need to re-sort it. This can be achieved very easily with the DataView class like this&amp;hellip; &lt;/p&gt;&lt;div id="code6676" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; SortDataTable(&lt;span style="color: #0000ff"&gt;ByRef&lt;/span&gt; Table &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; DataTable, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; SortString &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; DataTable
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; View &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; DataView(Table)
    View.Sort = SortString
    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; View.ToTable()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Man, that's almost too&amp;nbsp;easy! It is capable of sorting by multiple fields in any order using a very simple syntax similiar to the &amp;quot;ORDER BY&amp;quot; clause in SQL. As you could probably guess, it is more difficult to sort a generic list. Thanks to the inherent&amp;nbsp;flexibility of generics and reflection, however, it is possible to achieve identical functionality. And I've already done the work to make this happen. The class I created uses reflection, which does not perform fantastically, but it&amp;nbsp;offers up unprecedented flexibility. If performance/efficiency is of noteworthy concern&amp;nbsp;in your application, you might want to consider using &lt;a href="http://dotnetslackers.com/Community/blogs/simoneb/archive/2007/06/20/How-to-sort-a-generic-List_3C00_T_3E00_.aspx" target="_blank" title="SimoneB - Sort a Generic List (C#)"&gt;a type-specific approach&lt;/a&gt;.&amp;nbsp;Also, it was &lt;a href="http://stackoverflow.com/questions/438715/how-sort-a-system-collections-generic-list-in-vb-net/438739#438739" target="_blank" title="Stack Overflow - Comment from Jon Skeet"&gt;mentioned&lt;/a&gt; on Stack Overflow that C# developers can use inline delegates and VB9 developers can use lambda expressions, which I thought was an advanced yet elegant&amp;nbsp;approach. For the sake of simplicity, I just created an instance class that inherits IComparer and will work with any type on the .NET 2.0 framework...&lt;/p&gt;&lt;div id="code26839" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Collections
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Collections.Generic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Reflection

&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; Utility

    &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' Sort order enumeration&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Enum&lt;/span&gt; SortOrder
        Ascending
        Descending
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Enum&lt;/span&gt;

    &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' This instance class is used to sort a generic collection of object instances.&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' It automatically fetches the type and performs the necessary comparison(s) to sort.&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' &lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' To use, instantiate this class, set the sort string property, and pass this&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' instance to the internal Sort() function of your generic collection.&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' &lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' Example:&lt;/span&gt;
    &lt;span style="color: #008000"&gt;'''     Dim MyList As List(Of MyClassType) = 'Populate the list somehow&lt;/span&gt;
    &lt;span style="color: #008000"&gt;'''     Dim Sorter As New Sorter(Of MyClassType)&lt;br /&gt;    '''     Sorter.SortString = &amp;quot;Field1 DESC, Field2&amp;quot;&lt;/span&gt;
    &lt;span style="color: #008000"&gt;'''     MyList.Sort(Sorter) 'After this call, the list is sorted&lt;/span&gt;
    &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Sorter(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T)
        &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IComparer(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T)

        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Sort &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

        &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Instantiate the class.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;()

        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

        &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Instantiate the class, setting the sort string.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Example: &amp;quot;LastName DESC, FirstName&amp;quot;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; SortString &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            _Sort = SortString
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

        &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' The sort string used to perform the sort. Can sort on multiple fields.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Use the property names of the class and basic SQL Syntax.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Example: &amp;quot;LastName DESC, FirstName&amp;quot;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; SortString() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; _Sort &lt;span style="color: #0000ff"&gt;IsNot&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Sort.Trim()
                &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _Sort = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' This is an implementation of IComparer(Of T).Compare&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' Can sort on multiple fields, or just one.&lt;/span&gt;
        &lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; Compare(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; x &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; T, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; y &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; T) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IComparer(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T).Compare
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.IsNullOrEmpty(&lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.SortString) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; ERR &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = &amp;quot;&lt;span style="color: #8b0000"&gt;The property &lt;/span&gt;&amp;quot;&amp;quot;{0}&amp;quot;&amp;quot; does &lt;span style="color: #0000ff"&gt;not&lt;/span&gt; exist &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; type &amp;quot;&amp;quot;{1}&amp;quot;&amp;quot;&amp;quot;
                &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Type &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Type = &lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(T)
                &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Comp &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Comparer = Comparer.DefaultInvariant
                &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Info &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; PropertyInfo

                &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; Expr &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.SortString.Split(&amp;quot;&lt;span style="color: #8b0000"&gt;,&lt;/span&gt;&amp;quot;c)
                    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Dir &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; SortOrder = SortOrder.Ascending
                    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Field &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

                    Expr = Expr.Trim()

                    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Expr.EndsWith(&amp;quot;&lt;span style="color: #8b0000"&gt; DESC&lt;/span&gt;&amp;quot;) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                        Field = Expr.Replace(&amp;quot;&lt;span style="color: #8b0000"&gt; DESC&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty).Trim()
                        Dir = SortOrder.Descending
                    &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
                        Field = Expr.Replace(&amp;quot;&lt;span style="color: #8b0000"&gt; ASC&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty).Trim()
                    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

                    Info = Type.GetProperty(Field)

                    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Info &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                        &lt;span style="color: #0000ff"&gt;Throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; MissingFieldException(&lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Format(ERR, Field, Type.ToString()))
                    &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
                        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Result &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = Comp.Compare(Info.GetValue(x, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;), Info.GetValue(y, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;))

                        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Result &amp;lt;&amp;gt; 0 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Dir = SortOrder.Descending &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; Result * -1
                            &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
                                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; Result
                            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
                        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
                    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; 0
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;The meat of the class&amp;nbsp;lies in the Compare function, which is the essential drivetrain of the IComparer interface.&amp;nbsp;If you are not at all familiar with IComparer, you should&amp;nbsp;check out&amp;nbsp;this article on C# corner about &lt;a href="http://www.c-sharpcorner.com/UploadFile/yougerthen/104282008202917PM/1.aspx" target="_blank" title="C# Corner - Using IComparer to compare objects"&gt;comparing objects&lt;/a&gt;; it's quite a useful concept to grasp.&amp;nbsp;The class&amp;nbsp;is fully capable of sorting on one or multiple fields&amp;nbsp;of any type of object.&amp;nbsp;The &amp;quot;sort string&amp;quot;&amp;nbsp;uses the same basic syntax as the ORDER BY clause in SQL, and the field names to use&amp;nbsp;are actually the&amp;nbsp;property names within your class. All you have to do is instantiate the Sorter class, set the type and the sort string, and then pass the class instance to the Sort() function of your generic collection.&amp;nbsp;Following is a simple example (called ConsoleApplication149, for me!)&amp;nbsp;that fully demonstrates the flexibility...&lt;/p&gt;&lt;div id="code28131" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Module&lt;/span&gt; Module1

    &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Main()
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; People &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Person) = GetPeople()
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Sorter &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Sorter(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Person)

        Sorter.SortString = &amp;quot;&lt;span style="color: #8b0000"&gt;FirstName&lt;/span&gt;&amp;quot;
        People.Sort(Sorter)
        PrintResults(People, Sorter.SortString)

        Sorter.SortString = &amp;quot;&lt;span style="color: #8b0000"&gt;LastName DESC, FirstName, MiddleName&lt;/span&gt;&amp;quot;
        People.Sort(Sorter)
        PrintResults(People, Sorter.SortString)

        Sorter.SortString = &amp;quot;&lt;span style="color: #8b0000"&gt;DateOfBirth DESC&lt;/span&gt;&amp;quot;
        People.Sort(Sorter)
        PrintResults(People, Sorter.SortString)

        Console.ReadLine()
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetPeople() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Person)
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Result &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Person)

        &lt;span style="color: #0000ff"&gt;With&lt;/span&gt; Result
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;M&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Doe&lt;/span&gt;&amp;quot;, #1/1/1969#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Jane&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;A&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Doe&lt;/span&gt;&amp;quot;, #3/4/1972#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Paul&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;L&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Smith&lt;/span&gt;&amp;quot;, #2/1/1948#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Janet&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;A&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Doe&lt;/span&gt;&amp;quot;, #9/16/1975#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Patricia&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;B&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Smith&lt;/span&gt;&amp;quot;, #3/14/1952#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;John&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Matthew&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Doe&lt;/span&gt;&amp;quot;, #12/21/1988#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;James&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;L&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Doe&lt;/span&gt;&amp;quot;, #6/19/1990#))
            .Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Person(&amp;quot;&lt;span style="color: #8b0000"&gt;Patrick&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;O&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Smith&lt;/span&gt;&amp;quot;, #8/26/1993#))
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;With&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; Result
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; PrintResults(&lt;span style="color: #0000ff"&gt;ByRef&lt;/span&gt; People &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Person), &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; SortString &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
        Console.WriteLine(&amp;quot;&lt;span style="color: #8b0000"&gt;Sort String: &lt;/span&gt;&amp;quot; &amp;amp; SortString)
        Console.WriteLine()

        &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; Per &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Person &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; People
            Console.WriteLine(Per.ToString())
        &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;

        Console.WriteLine()
        Console.WriteLine()
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Module&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Person

    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _First &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Middle &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Last &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Dob &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;()

    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; FirstName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; MiddleName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; LastName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; DateOfBirth &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;)
        _First = FirstName
        _Middle = MiddleName
        _Last = LastName
        _Dob = DateOfBirth
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; FirstName() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _First
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            _First = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; MiddleName() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Middle
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            _Middle = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; LastName() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Last
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            _Last = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; DateOfBirth() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Dob
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;)
            _Dob = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Overrides&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; ToString() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.FirstName.PadRight(15, &amp;quot;&lt;span style="color: #8b0000"&gt; &lt;/span&gt;&amp;quot;) &amp;amp; _
               &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.MiddleName.PadRight(10, &amp;quot;&lt;span style="color: #8b0000"&gt; &lt;/span&gt;&amp;quot;) &amp;amp; _
               &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.LastName.PadRight(15, &amp;quot;&lt;span style="color: #8b0000"&gt; &lt;/span&gt;&amp;quot;) &amp;amp; _
               &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.DateOfBirth.ToString(&amp;quot;&lt;span style="color: #8b0000"&gt;yyyy-MM-dd&lt;/span&gt;&amp;quot;)
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Simple as that!&amp;nbsp;I've grown to love this class, and I hope you too find it useful!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=c0dMYRwl5p4:ZUfDyhbsrQk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=c0dMYRwl5p4:ZUfDyhbsrQk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=c0dMYRwl5p4:ZUfDyhbsrQk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=c0dMYRwl5p4:ZUfDyhbsrQk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=c0dMYRwl5p4:ZUfDyhbsrQk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2009/02/sorting-generic-list-dynamically-in-vbnet.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2009/02/sorting-generic-list-dynamically-in-vbnet.aspx#comments</comments>
      <pubDate>Tue, 03 Feb 2009 14:44:27 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2009/02/sorting-generic-list-dynamically-in-vbnet.aspx</guid>
      <category>VB.NET</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">27</slash:comments>
    </item>
    <item>
      <title>Javascript Learning Pains - parseInt does not work!</title>
      <description>&lt;p&gt;Javascript is a very unique language, and I think that has become more and more apparent over the years. &lt;a href="http://javascript.crockford.com/javascript.html" target="_blank" title="Douglas Crockford - Javascript"&gt;Crockford said it best&lt;/a&gt; - it's the worlds most misunderstood programming language. And yet it has somehow managed to evolve into a sheer necessity of the web. I can blatantly recall my very first programming experience with Javascript, back in 1998. I spent over an hour trying to figure out why my one line of code to get a form element was not working. Then I found out that Javscript was a case-sensitive language, and this really pissed me off. I could use whatever case I wanted in HTML, so why does Javascript have to be any different?!&amp;nbsp;Regardless of your level of experience as a programmer (in general), you&amp;nbsp;should probably&amp;nbsp;expect some introductory hiccups upon first learning Javascript. I believe that such initial frustrations are&amp;nbsp;why the language initially got such a bad rap. To become an expert, you have to be persistent, inquisitive, and down-right stubborn.&lt;/p&gt;&lt;p&gt;The other day, a co-worker of mine was flipping his wig over the parseInt() function. It was not working consistently, which was probably pretty aggravating. Hell, I know it was aggravating. He came to the realization that it was failing everytime the given number had a leading zero. No, this is &lt;em&gt;not&lt;/em&gt; a bug. The problem (of course!) was that he was not specifying a radix. Yes, parseInt() has two parameters, not just one. When you do not specify a radix, it makes an educated guess at what it should be, based on a simple evaluation of the input string. &lt;a href="http://www.w3schools.com/jsref/jsref_parseInt.asp" target="_blank" title="W3Schools - ParseInt"&gt;W3Schools&lt;/a&gt; clearly states&amp;hellip;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If the string begins with &amp;quot;0x&amp;quot;, the radix is 16 (hex)&lt;/li&gt;&lt;li&gt;If the string begins with &amp;quot;0&amp;quot;, the radix is 8 (octal)&lt;/li&gt;&lt;li&gt;Otherwise, the radix is 10 (decimal)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;That said, passing a value of &amp;quot;080&amp;quot; without specifiying a radix is always going to return zero because it is not a valid &lt;a href="http://en.wikipedia.org/wiki/Octal" target="_blank" title="Octal - Wikipedia"&gt;Octal&lt;/a&gt; value. Go ahead, &lt;a href="javascript:alert(parseInt('080'));"&gt;see for yourself&lt;/a&gt;. The fix is really simple, and becomes painfully obvious once you understand the above. Make sure to always specify a decimal radix, and &lt;a href="javascript:alert(parseInt('080', 10));"&gt;it will work&lt;/a&gt;. People who have no patience for specifications might realize that using parseFloat instead of parseInt is also a potential workaround. But if you are like me, you have to know &lt;em&gt;why&lt;/em&gt; something does not work. And this is just one of the few oddball issues you can expect to encounter if you are&amp;nbsp;new to&amp;nbsp;Javascript.&lt;/p&gt;&lt;p&gt;If you have managed to master the Javascript language without having at least one aggravating encounter like this, you must be inhuman!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=pFdqPmI5oy8:tot4An6vcvE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=pFdqPmI5oy8:tot4An6vcvE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=pFdqPmI5oy8:tot4An6vcvE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=pFdqPmI5oy8:tot4An6vcvE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=pFdqPmI5oy8:tot4An6vcvE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2009/01/javascript-learning-pains-parseint-does-not-work.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2009/01/javascript-learning-pains-parseint-does-not-work.aspx#comments</comments>
      <pubDate>Fri, 30 Jan 2009 09:42:35 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2009/01/javascript-learning-pains-parseint-does-not-work.aspx</guid>
      <category>Javascript</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments>
    </item>
    <item>
      <title>Creating an Excel Spreadsheet from a Generic List in VB.NET</title>
      <description>&lt;p&gt;I'm a huge fan of generic lists. They have numerous benefits, and because of that I've been campaigning them at work to the other programmers. The response has been very good. Although given that our previous method was powered by DataTables, it is not much of a surprise that generic lists have evolved into the preference. A question came up today about adding the capability to export a GridView's data source to a Microsoft Excel spreadsheet, and it just so happens the GridView was bound to a List. This is the first time this has come up. We've had several grids export to Excel, and a common function to handle most of the workload was in place, but unfortuntely it was built for a DataTable instance. This task was accomplished fairly simply with DataTables, because it was unnecessary to worry about the parameter type - it was always a DataTable. The function loops through all the rows and builds a tab/line delimited string of data and returns it. DataTables also made it simple to get the name of the columns (which may be used as column headers). Thanks to generics and reflection, I was able to build a function that performs the same task with equivalent flexibility&amp;hellip; &lt;/p&gt;&lt;div id="code97848" class="code"&gt;&lt;pre&gt;&lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Returns a string that can be streamed out to an Excel spreadsheet.&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Records are delimited by a line feed (13). Fields are delimited by a tab (9).&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;param name=&amp;quot;Objects&amp;quot;&amp;gt;The list of class instances to convert&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;param name=&amp;quot;IncludeHeadings&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Include a heading record at the beginning of the string? &lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Headings will be derived from the property name.&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;param name=&amp;quot;IncludeReadOnlyProperties&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Include ReadOnly properties in the response for each instance?&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;returns&amp;gt;Nothing if the given collection is empty&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Shared&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; ListToString(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T)(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; Objects &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T), &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; IncludeHeadings &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; IncludeReadOnlyProperties &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Objects &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;OrElse&lt;/span&gt; Objects.Count = 0 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; TAB &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = Convert.ToChar(9)
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; LF &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = Convert.ToChar(13)
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Result &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; StringBuilder()
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Type &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Type = &lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(T)
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Props &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; PropertyInfo() = Type.GetProperties()

    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; IncludeHeadings &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; Prop &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; PropertyInfo &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; Props
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Prop.CanWrite &lt;span style="color: #0000ff"&gt;OrElse&lt;/span&gt; IncludeReadOnlyProperties &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                Result.Append(Prop.Name)
                Result.Append(TAB)
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; Obj &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt; &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; Objects
        Result.Append(LF)

        &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; Prop &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; PropertyInfo &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; Props
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Prop.CanWrite &lt;span style="color: #0000ff"&gt;OrElse&lt;/span&gt; IncludeReadOnlyProperties &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                Result.Append(Prop.GetValue(Obj, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;).ToString())
                Result.Append(TAB)
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; Result.ToString()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;

&lt;span style="color: #008000"&gt;''' &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Returns a string that can be streamed out to an Excel spreadsheet.&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Records are delimited by a line feed (13). Fields are delimited by a tab (9).&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' Includes headings. Excludes read-only properties.&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;param name=&amp;quot;Objects&amp;quot;&amp;gt;The list of class instances to convert&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span style="color: #008000"&gt;''' &amp;lt;returns&amp;gt;Nothing if the given collection is empty&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Shared&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; ListToString(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T)(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; Objects &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; T)) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; ListToString(Objects, &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;)
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;And of course, I should mention that Reflection in the .NET framework is &lt;a href="http://www.west-wind.com/WebLog/posts/351.aspx" target="_blank" title="Rick Strahl - .Net Reflection and Performance"&gt;not the most efficient approach&lt;/a&gt; in the world. That said, if you are setting up something to process batch, you might want to consider using a strongly-typed method. However, if the intended functionality is not expected to be used frequently, then this should work just fine for you. You have to make an educated decision on whether or not the efficiency impact is crucial enough to supercede the convenience factor of having a global function. In our case, it certainly was not.&lt;/p&gt;&lt;p&gt;Also, I want to make it clear that I am well-aware of the &lt;a href="http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html" title="Matt Berseth - Export GridView to Excel"&gt;approach&lt;/a&gt; to exporting GridViews to excel that renders the grid's HTML and relies on Excel to interpret it correctly. So there is no need to point that out to me (although somebody probably will anyways). I am not really a fan of this method. It has it's purpose and it is undeniably simplistic, but it was not right for me. If you are in a similiar situation (you need to get at the data source of the grid, or you aren't even using a visual grid), you'll appreciate the function above.&lt;/p&gt;&lt;p&gt;Here's a quick and dirty example of how to use the function...&lt;/p&gt;&lt;div id="code8830" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Structure&lt;/span&gt; Employee
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Id &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _Name &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _DateHired &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime

    &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; Id &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; Name &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; DateHired &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime)
        _Id = Id
        _Name = Name
        _DateHired = DateHired
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;ReadOnly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Id() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Id
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Name() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _Name
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            _Name = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; DateHired() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _DateHired
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime)
            _DateHired = value
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Structure&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Main()
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; MyList &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(&lt;span style="color: #0000ff"&gt;Of&lt;/span&gt; Employee)
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; RightNow &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime = DateTime.Now
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Export &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

    MyList.Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Employee(1, &amp;quot;&lt;span style="color: #8b0000"&gt;Josh Stodola&lt;/span&gt;&amp;quot;, RightNow.AddDays(-365)))
    MyList.Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Employee(2, &amp;quot;&lt;span style="color: #8b0000"&gt;John Doe&lt;/span&gt;&amp;quot;, RightNow.AddDays(-31)))
    MyList.Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Employee(3, &amp;quot;&lt;span style="color: #8b0000"&gt;Jane Doe&lt;/span&gt;&amp;quot;, RightNow))

    Export = Utility.ListToString(MyList)

    Console.WriteLine()
    Console.WriteLine(Export)
    Console.WriteLine()
    Console.ReadLine()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Hope you found this useful! Oh, and accept my apologies for the inexcusable lack of blog posts lately.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=7BhNBbux6lE:MUc-4UlJVJo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=7BhNBbux6lE:MUc-4UlJVJo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=7BhNBbux6lE:MUc-4UlJVJo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=7BhNBbux6lE:MUc-4UlJVJo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=7BhNBbux6lE:MUc-4UlJVJo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2009/01/creating-an-excel-spreadsheet-from-generic-list-in-vbnet.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2009/01/creating-an-excel-spreadsheet-from-generic-list-in-vbnet.aspx#comments</comments>
      <pubDate>Mon, 26 Jan 2009 18:37:06 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2009/01/creating-an-excel-spreadsheet-from-generic-list-in-vbnet.aspx</guid>
      <category>VB.NET</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">6</slash:comments>
    </item>
    <item>
      <title>Third Week of August</title>
      <description>&lt;p&gt;It's finally that time of year again. The time to shut down the computers. The time to relax and put the mind at ease. The time to pigeonhole the daily tasks that are seemingly important, and realize that they are actually humdrum. The time to part myself from this electronics-infatuated lifestyle, in an effort to maintain natural sanity.&lt;/p&gt;&lt;p&gt;It's the third week of August, and that means one thing to me: fishing time. Tomorrow morning, bright and early, I will be on my way to Minnesota again to spend a computer-free week with nature, with the mere objective of chillaxing. This is an annual vacation for me, and I could almost classify such a trip as essential for anybody who uses computers for several hours a day (given that you are not disturbed enough to say you'd have &lt;a href="http://www.codinghorror.com/blog/archives/000770.html" target="_blank" title="Jeff Atwood would have sex with his computers"&gt;sex with computers&lt;/a&gt;). Escaping the shackles that are the keyboard and mouse, even for a day or two, has a profound effect on my general outlook towards life. Spending 70 hours of the week behind a computer is somewhat humbling, even if you have a sincere passion for it. I certainly do not want to become one who thouroughly enjoys doing something so much, but does it so often that he/she ends up growing tired of it.&lt;/p&gt;&lt;p&gt;To&amp;nbsp;combat that nightmare of a possibility, I just get out on a beautiful lake on a beautiful day and forget about everything (except my way home of course). And it does the trick for me. The best coding day of the year is always the first day after I return from vacation. It's like a weird sort of revelation. So if you are one who works behind a computer for a living, and then retires to the household to spend more time on the computer, please do yourself a favor and make an effort to escape on a yearly basis (at least). And do not bring your laptop with you!&lt;/p&gt;&lt;p&gt;As a result of my absence, replies to email and comments will be delayed until August 24th.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=JWhEGIaC1pI:4jIn_UWpt4E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=JWhEGIaC1pI:4jIn_UWpt4E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=JWhEGIaC1pI:4jIn_UWpt4E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=JWhEGIaC1pI:4jIn_UWpt4E:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=JWhEGIaC1pI:4jIn_UWpt4E:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/08/third-week-of-august.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/08/third-week-of-august.aspx#comments</comments>
      <pubDate>Fri, 15 Aug 2008 12:19:10 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/08/third-week-of-august.aspx</guid>
      <category>My Life</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">2</slash:comments>
    </item>
    <item>
      <title>My New Office</title>
      <description>&lt;p&gt;I've been saving up money for a little while now, with hopes of revamping my office at home to accomodate my ever-growing computing &lt;strike&gt;needs&lt;/strike&gt; wants. I was finally able to purchase all that I wanted, and now I am quite happy with my home within my home. It's amazing how dropping a few grand on yourself can change your whole outlook on life. The ultimate addition to my office is obviously&amp;nbsp;a new computer, but before I could go down that route I decided it would be best to get a new desk first. I'm sold on the &lt;a href="http://www.codinghorror.com/blog/archives/000012.html" target="_blank" title="Jeff Atwood: Multiple Monitors"&gt;multiple monitors&lt;/a&gt; concept, so I needed&amp;nbsp;a spacious desk with room&amp;nbsp;for at least two big LCDs for the new machine. Also, my old computer (ha, I can call it old now) still has plenty of life left, so I needed a desk that could accomodate &lt;em&gt;it&lt;/em&gt; as well, without being cluttered. After shopping at a multitude of stores around town, I threw in the towel on the traditional market and turned to the web. I should've done that to begin with; I wasted too much time and gas wandering aimlessly, and I had to put up with a bunch of annoying salesmen. I don't need to be persuaded into believing that L-shaped desks are far superior to anything else! Damn salesmen. Anyways, I ended up settling on a desk from &lt;a href="http://www.versatables.com/" target="_blank" title="VersaTables"&gt;VersaTables&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;I Heart VersaTables&lt;/h3&gt;&lt;p&gt;&lt;img src="http://blog.josh420.com/images/2008/07/desk.png" border="0" alt="My VersaTables Desk" width="315" height="210" align="left" /&gt;They specialize in computer furniture for classrooms, computer labs, and medical establishments. They have adjustable desks, wall mount setups, carts, drafting tables, etc. No, I am not setting up a computer lab here, but I like these styles of desks because they are built to last. I purchased the &lt;a href="http://www.versatables.com/pages/products/school/cd7230.php" target="_blank" title="VersaTables: 72&amp;quot; Enclosed Classroom Desk"&gt;72&amp;quot; Encosed Classroom Desk&lt;/a&gt;, and I think it is fantastic. The first thing I noticed about this desk is its level of sturdiness. I could treat it like a trampoline and it would not budge. Also, they probably could've just dropped it right from the FedEx airplane, because it was packed better than anything I've ever seen. Not a single chip or scratch in the black paint, I was very impressed. You might be wondering, where are the drawers? It has none. I had a desk with drawers before, and I never used them. My life is practically paperless, so I really don't have a need for file cabinets and drawers; they just get in the way. In my eyes, the lack of drawers was actually a selling point. The desk comes with a nice cable management tray in the back, which helps you organize your coords and reduce the amount of exposure. I accessorized this beast by getting two enclosed CPU holders, an adjustable keyboard arm and tray for my new PC, and a keyboard drawer for the other machine. With these accessories, I have the whole desk surface to work with (aside from the space required for the monitors and speakers, of course). It's worth mentioning that the keyboard arm I purchased was not very sturdy, and it did not slide as smoothly as it should. I simply called them and talked about it and they were happy to send me a new one free of charge (and they spoke to me like a person, in clear English). Now it works perfectly.&amp;nbsp;They didn't even ask me to ship the other one back. Now &lt;em&gt;that&lt;/em&gt; is customer service. These desks are made in the USA and come with a lifetime warranty. I could &lt;strong&gt;not &lt;/strong&gt;be happier.&lt;/p&gt;&lt;h3&gt;My Buttocks Rejoice&lt;/h3&gt;&lt;p&gt;&lt;img src="http://blog.josh420.com/images/2008/07/chair.png" border="0" alt="Steelcase Leap" width="100" height="155" align="right" /&gt;Unfortunately, I was completely unable to find any Herman-Miller dealers around here that would let me take one of their prestine chairs for a test-trial, so I threw the &lt;a href="http://www.hermanmiller.com/aeron/" target="_blank" title="Herman Miller Aeron"&gt;Aeron&lt;/a&gt; and &lt;a href="http://www.hermanmiller.com/mirra/" target="_blank" title="Herman Miller Mirra"&gt;Mirra&lt;/a&gt; options right out the window. I've heard great things about them, but I guess they should do a better job of marketing; I had to make an effort just to locate a dealer, and I still was unable to reach a human being. I ended up purchasing an all-black &lt;a href="http://www.steelcase.com/na/leap_products.aspx?f=11852" target="_blank" title="Steelcase Leap"&gt;Steelcase Leap&lt;/a&gt; off eBay for roughly $450, and so far I am pleased with it. Although I do wish it had a little more support for the upper back. I am 6'4&amp;quot; so perhaps I need more support in this area than the average user. One remarkable thing about this chair is that it reclines &lt;em&gt;very&lt;/em&gt; comfortably. I never thought leaning back could feel so good! In other chairs that I have sat in, leaning back tends to increase the pressure on my spine. The Leap does a good job of distributing the pressure evenly with the so-called &amp;quot;Natural Glide System&amp;quot;. There is an ungodly amount of adjustments on this chair. That said, you can expect it to take some time to find your &amp;quot;spot&amp;quot;, and don't dare let anybody else sit in it!&lt;/p&gt;&lt;h3&gt;The Ultimate PC&lt;/h3&gt;&lt;p&gt;I've always wanted to build my own PC. Not only do you get a bigger bang for your buck, but there is a certain sense of pride that comes along with it. This was my first build, and I will probably never turn back to retail. As a control-freak, I just love being able to say &amp;quot;Yup, I built this&amp;quot;. Ever since I read the &lt;a href="http://www.codinghorror.com/blog/archives/000918.html" target="_blank" title="Jeff Atwood: Ultimate Developer Rig"&gt;post&lt;/a&gt; from the coding whore himself, Jeff Atwood, I was intrigued to give it a shot. And, as planned, I tried to go all-out. This is what my new&amp;nbsp;machine consists of&amp;hellip;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16811129024" target="_blank" title="Antec Sonata III Black Case"&gt;Antec Sonata III Black Case&lt;/a&gt; - &lt;strong&gt;$124.95&lt;/strong&gt; &lt;div&gt;This is a very nice and quiet case, although I am not so sure that opening a door to reach my DVD drives is desired. It doesn't really bother me, but I could see how it could be a major annoyance to some. Also, I think it could be ventilated better. Came with a really good 500W power supply.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16813128336" target="_blank" title="GIGABYTE GA-X48-DS4"&gt;GIGABYTE GA-X48-DS4 LGA 775 Intel X48 ATX Motherboard&lt;/a&gt; - &lt;strong&gt;$224.95&lt;/strong&gt; &lt;div&gt;This was probably more of a motherboard than I needed, but it's very nice indeed. I think the documentation could have been better.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16819115027" target="_blank" title="Intel Core 2 Quad Q6700"&gt;Intel Core 2 Quad Q6700 Kentsfield 2.66Ghz Quad-Core Processor&lt;/a&gt; - &lt;strong&gt;$274.99&lt;/strong&gt; &lt;div&gt;This CPU is incredible. I considered getting an Extreme, but decided it was no way worth the price. I haven't overclocked this CPU yet (too chicken), but I'll bet it can handle it well. I plan to OC in the future, perhaps when I grow some balls.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16814127329" target="_blank" title="MSI NX8800GT 512MB OC GeForce Video Card"&gt;MSI NX8800GT 512MB OC GeForce 256-bit GDDR3 Video Card&lt;/a&gt; - &lt;strong&gt;$169.99&lt;/strong&gt; &lt;div&gt;This is an impressive video card, it handles my dual monitors like a champ. Such a work horse. Loaded with features I will probably never use. Overclocked to 660 MHz, this thing flies at decent temperatures. It's big, and it packs a punch.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;(2) &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16820146726" target="_blank" title="mushkin 4GB (2x2GB) DDR2 SDRAM"&gt;mushkin 4GB (2x2GB) DDR2 SDRAM 800 Dual Channel&lt;/a&gt; - &lt;strong&gt;$217.98&lt;/strong&gt; &lt;div&gt;This is 8GB of high quality RAM. Extremely fast. Came with an exceptional $25 mail-in rebate, too.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822136260&amp;amp;Tpk=velociraptor%2b300GB" target="_blank" title="Western Digital VelociRaptor 300GB 10000 RPM Hard Drive"&gt;Western Digital VelociRaptor 300GB 10,000 RPM Hard Drive&lt;/a&gt; - &lt;strong&gt;$299.99&lt;/strong&gt; &lt;div&gt;This&amp;nbsp;is the boot drive, and I cannot get over how fast and how quiet this hard drive is. It is literally sickening. Expensive, but I truly think it is worth it. &lt;a href="http://www.codinghorror.com/blog/archives/001157.html" target="_blank" title="Jeff Atwood: Hardware Recommendations for Rob Conery"&gt;Atwood even recommended it to RobCon&lt;/a&gt;. Get it. Now.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822136073" target="_blank" title="Western Digital Caviar 500GB 7200 RPM Hard Drive"&gt;Western Digital Caviar 500GB 7,200 Hard Drive&lt;/a&gt; - &lt;strong&gt;$79.99&lt;/strong&gt; &lt;div&gt;This is my secondary drive that I use primarily for multimedia storage. I just might buy a couple more of these, they are extremely cheap and would work great for backups. Could be quieter, of course, but the Antec case comes with these fantastic rubber grommets to help eliminate vibration noise.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16835118019&amp;amp;Tpk=zalman%2bcnps9700" target="_blank" title="Zalman CNPS9700 2 Ball CPU Cooler"&gt;Zalman CNPS9700 2 Ball CPU Cooler&lt;/a&gt; - &lt;strong&gt;$53.99&lt;/strong&gt; &lt;div&gt;Supposed to be an excellent cooler, but I expected more. After 4 hours of Prime95, Core 0 had a temperature of 65C. I expected much lower than that; I'm not even overclocked!&lt;/div&gt;&lt;/li&gt;&lt;li&gt;(2) &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16827151171" target="_blank" title="Samsung 22X DVD Burner SATA"&gt;Samsung 22X DVD Burner SATA&lt;/a&gt; - &lt;strong&gt;$57.98&lt;/strong&gt; &lt;div&gt;They work great, but I wish they were quieter when burning. Go ahead, call me a noise freak.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;(2) &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16824009094" target="_blank" title="Acer 22&amp;quot; Widescreen LCD Monitor"&gt;Acer Black 22&amp;quot; Widescreen LCD Monitor&lt;/a&gt; - &lt;strong&gt;$439.98&lt;/strong&gt; &lt;div&gt;A great deal, has excellent picture quality. I did have one dead pixel in each of them, but they are barely noticeable, only when the entire screen is black. I didn't notice them for 2 days.&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16832116378" target="_blank" title="Windows XP 64-bit"&gt;Windows XP 64-bit&lt;/a&gt; - &lt;strong&gt;$139.99&lt;/strong&gt; &lt;div&gt;Since I wholeheartedly feel that Vista is the biggest heap of shit Microsoft has released since &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Bob" target="_blank" title="Wikipedia: Microsoft Bob"&gt;Bob&lt;/a&gt;, I had to go with good ol' XP. And let me tell you, this OS is very fast. Excitingly fast. Thus far, I have had no problems whatsoever. It runs intensive programs (such as Visual Studio and Photoshop) like a true champ.&amp;nbsp;One complaint: it's too fast. I find the instantaneous appearance of windows somewhat&amp;nbsp;disorienting. I should get used to it :)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I also got a &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16823109156" target="_blank" title="Microsoft ComfortCurve Keyboard"&gt;Microsoft ComfortCurve Keyboard&lt;/a&gt;, a &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16826105148" target="_blank" title="Microsoft 5-button IntelliMouse"&gt;5-Button Wired IntelliMouse&lt;/a&gt;, and &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16836121014" target="_blank" title="Logitech Speaker System"&gt;Logitech Speakers&lt;/a&gt; (I already have a quality Plantronics headset). In the end, I spent about &lt;strong&gt;$2,250&lt;/strong&gt; on this machine. Note: these prices are as of early July 2008. And that, folks, is my ultimate PC! I love it, and I am guessing it will last me&amp;nbsp;a good&amp;nbsp;five years, at least.&lt;/p&gt;&lt;p&gt;I've never made a post like this before, I hope you enjoyed it!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=bfgxF27PEfs:3e38_6rEza8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=bfgxF27PEfs:3e38_6rEza8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=bfgxF27PEfs:3e38_6rEza8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=bfgxF27PEfs:3e38_6rEza8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=bfgxF27PEfs:3e38_6rEza8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/07/my-new-office.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/07/my-new-office.aspx#comments</comments>
      <pubDate>Wed, 30 Jul 2008 21:12:17 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/07/my-new-office.aspx</guid>
      <category>My Life</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">13</slash:comments>
    </item>
    <item>
      <title>Using Sprite Images with &lt;input type="image" /&gt; for a Hover Effect</title>
      <description>&lt;p&gt;I am a huge fan of &lt;a href="http://www.alistapart.com/articles/sprites" target="_blank" title="A List Apart: CSS Sprites"&gt;CSS sprites&lt;/a&gt;, a technique used to create image-based hover effects on a web page. It's clever and very efficient because both &amp;quot;image states&amp;quot; are contained in a single image, eliminating the need to make two requests to the server.&amp;nbsp;It tends to go hand-in-hand with &lt;a href="http://www.mezzoblue.com/tests/revised-image-replacement/" target="_blank" title="Dave Shea: Image Replacement"&gt;image replacement&lt;/a&gt; to create an appealing effect while retaining accessibility and search engine optimization. Having to use background images sort of limits the flexibility to an extent. I realized this when I wanted to use sprites with the &amp;lt;input type=&amp;quot;image&amp;quot; /&amp;gt; tag for submitting a form. Since this tag sets the path to the image as an attribute, the classic method of applying sprites with background images cannot be used. The same challenge is presented with the &amp;lt;img&amp;gt; tag. There are alternative routes, such as using two separate images and wiring up some Javascript to pre-load the hover image and change the SRC attribute of the input tag onmouseover. But, since I love sprites so much, I wanted to try and make it happen that way. It's not overly difficult nor complex, but I thought I would make a post out of it anyways. For an example, I will be using the following image as the sprite&amp;hellip;&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/07/submit.png" border="0" alt="Example Submit Button Sprite Image" width="200" height="80" /&gt;&lt;/p&gt;&lt;p&gt;The plan is to make the top half of the image visible by default. When the mouse hovers over it, the bottom half should show (this could be vice-versa very easily). I'm assuming you understand the concept behind sprites, so I won't waste any more time explaining their structure and benefits. It's worth mentioning that the dimensions of the image above ar 200x80. To make this work, an extra &amp;lt;div&amp;gt;&amp;nbsp;will be&amp;nbsp;needed&amp;hellip;&lt;/p&gt;&lt;div id="code30713" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;submitButton&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;image&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;src&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;submit.png&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;alt&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Submit Form&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Since the &amp;lt;div&amp;gt; is a container for the image, we can set a specific height and hide the overflow so that the default state of our image (the top)&amp;nbsp;is the only thing showing&amp;hellip; &lt;/p&gt;&lt;div id="code52023" class="code"&gt;&lt;pre&gt;&lt;span style="color: #800000"&gt;#submitButton&lt;/span&gt; {
  &lt;span style="color: #ff0000"&gt;cursor&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;pointer&lt;/span&gt;;       &lt;span style="color: #008000"&gt;/* Give it the hand cursor, like a link */&lt;/span&gt;
  &lt;span style="color: #ff0000"&gt;height&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;40px&lt;/span&gt;;          &lt;span style="color: #008000"&gt;/* Image has a height of 80px, only show the first half */&lt;/span&gt;
  &lt;span style="color: #ff0000"&gt;overflow&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;hidden&lt;/span&gt;;      &lt;span style="color: #008000"&gt;/* Hide the overflow */&lt;/span&gt;
  &lt;span style="color: #ff0000"&gt;width&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;200px&lt;/span&gt;;          &lt;span style="color: #008000"&gt;/* Width of the image */&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;After that, setting the image to display the other half when moused over is as easy as adding a negative top-margin on the :hover pseudo-element of the &amp;lt;div&amp;gt;&amp;hellip; &lt;/p&gt;&lt;div id="code74829" class="code"&gt;&lt;pre&gt;&lt;span style="color: #800000"&gt;#submitButton&lt;/span&gt;:&lt;span style="color: #800000"&gt;hover&lt;/span&gt; &lt;span style="color: #800000"&gt;input&lt;/span&gt; {
  &lt;span style="color: #ff0000"&gt;margin-top&lt;/span&gt;:&lt;span style="color: #0000ff"&gt;-40px&lt;/span&gt;;    &lt;span style="color: #008000"&gt;/* Negative height of half the sprite, to push the image up */&lt;/span&gt;
}
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;And that is all there is to it! I have tried this in IE7, Firefox 2, Opera 9, and Safari and it worked just fine. IE6 did not produce a hover effect, but it degrades gracefully by just showing the top half. If you discover a browser that causes abnormal results, please enlighten me and the future readers of this post by posting a comment. I've setup a live demo and a ZIP file for you to download.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;div&gt;&lt;a href="http://blog.josh420.com/examples/InputImageSprites/" target="_blank" title="View Demo"&gt;View Demo&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;&lt;a href="http://blog.josh420.com/examples/InputImageSprites.zip" title="Download the Code"&gt;Download the Code&lt;/a&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Have fun!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=vTmQgLriNNc:qxt-_Dj1wmQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=vTmQgLriNNc:qxt-_Dj1wmQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=vTmQgLriNNc:qxt-_Dj1wmQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=vTmQgLriNNc:qxt-_Dj1wmQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=vTmQgLriNNc:qxt-_Dj1wmQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/07/using-sprite-images-with-input-typeimage-for-hover-effect.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/07/using-sprite-images-with-input-typeimage-for-hover-effect.aspx#comments</comments>
      <pubDate>Tue, 29 Jul 2008 22:45:46 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/07/using-sprite-images-with-input-typeimage-for-hover-effect.aspx</guid>
      <category>CSS</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">5</slash:comments>
    </item>
    <item>
      <title>The Cookie-Cutter Image Hover Effect</title>
      <description>&lt;p&gt;Today I am going to share an interesting and super-cool way to create a dynamic hover effect for images. I call this flexible format the &amp;quot;cookie-cutter effect&amp;quot;, and you'll find out why in a moment. First, I shall go off on a tangent to maintain my reputation. This day in age, alot of navigational bars on web sites are image-based. Designers prefer to use graphics because it helps make the navigation more stunning and visually appealing (eye candy). Another thing that is becoming nearly mandatory is a hover effect for each of the links, meaning the image changes slightly when the user has positioned their cursor over it. This sends an instant visual cue to the user and lets them know exactly what they are pointing at. It may seem a little silly to think a user does not know where their mouse is pointed, but that certainly is not the case. The map in the center of your local shopping mall with a big arrow that says &amp;quot;You are here&amp;quot; is not silly either, it is actually helpful to some. Unfortunately, there is a pretty durastic downfall to using graphics for key elements such as navigation: they seriously lack&amp;nbsp;extensibility. Say you want to increase the brightness of the hover effect by a few shades. This task, at the very least, requires knowledge of a graphics editing program. Usually some design talent is required too. In many cases this situation cannot be avoided, but the approach that I am discussing in this post will at the very least allow greater flexibility than the norm.&lt;/p&gt;&lt;h3&gt;Let's Begin&lt;/h3&gt;&lt;p&gt;&lt;img src="http://blog.josh420.com/images/2008/06/josh1.png" alt="Demo Image 1" width="200" height="90" align="right" /&gt;To demonstrate the technique, I went ahead and created some random image with my first name next to an odd shape. I stuck the shape in there to illustrate that this approach is applicable to more than just textual images. In the end, the main part of this image (currently white) will be able to be changed to any color we want using&amp;nbsp;&lt;strong&gt;CSS only&lt;/strong&gt;. Consider the base image to the right as &lt;a href="http://en.wikipedia.org/wiki/The_Opposite" target="_blank" title="Seinfeld - The Opposite (fantastic episode)"&gt;the opposite&lt;/a&gt; of what we want. The plan is to turn the text into the transparent part, and the background of the the image to a solid white. The result will be somewhat of a template, if you will. We will be able to use &lt;em&gt;any&lt;/em&gt; background color or image behind it to essentially alter the part of the image that is actually intended to represent the foreground. I became aware of the usefulness of this concept when I read &lt;a href="http://jasonsantamaria.com/" target="_blank" title="Jason Santa Maria"&gt;Jason Santa Maria&lt;/a&gt;'s post the other day about &lt;a href="http://jasonsantamaria.com/articles/a-new-day/" title="A New Day"&gt;his new blogging expedition&lt;/a&gt;. He intends for each post to have its own design theme/color scheme. Currently, he has the inverse effect of what I am demonstrating in this post; the &lt;em&gt;background color&lt;/em&gt; of his navigational&amp;nbsp;links change. This was accomplished by using normal transparent images like the one above, and is still flexible and cool. But, what if you want the &lt;em&gt;color of the text&lt;/em&gt; to change? I'm sure Jason knows the answer.&lt;/p&gt;&lt;h3&gt;Cut It Out&lt;/h3&gt;&lt;p&gt;&lt;img src="http://blog.josh420.com/images/2008/06/cookie-cutter.jpg" border="0" alt="Cookie Cutter &amp;amp; Dough" hspace="3" width="250" height="125" align="right" /&gt;And this is where the term cookie-cutter is derived. When you cut shapes out of the dough, you are left with with a transparent version of the shape (commonly referred to as a cutout). You could slide a piece of regular paper underneath it to make the shape display as white. You could quickly and easily switch to a yellow paper and change the color of the entire shape. You could even slide a photo of yourself under it! This &amp;quot;theory&amp;quot; offers up quite a bit of flexibility, and I am going show you how to bring it to the web. I guess the toughest part of replicating this concept is the actual creation the image. I will be using Adobe Photoshop CS2 to do it. This amazing piece of software makes the task&amp;nbsp;much easier to accomplish than I originally anticipated.&lt;/p&gt;&lt;h3&gt;Photoshop Time&lt;/h3&gt;&lt;p&gt;I am a Photoshop newbie, so this should not be difficult to follow. To start off, here is a screenshot of my Photoshop window&amp;nbsp;to show you where I am at&amp;nbsp;(I added a temporary black background so the text is more legible)&amp;hellip;&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop1.png" alt="Photoshop Screenshot #1" width="673" height="571" /&gt;&lt;/p&gt;&lt;p&gt;First,&amp;nbsp;merge the text and shape layers together&amp;hellip;&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop2.png" border="0" alt="Merge Layers" width="384" height="506" /&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Execute the Select All command by pressing Ctrl + A. Then select the Move Tool &lt;img src="http://blog.josh420.com/images/2008/06/move-tool.png" border="0" alt="Move Tool" width="25" height="21" /&gt;&amp;nbsp;from the toolbox. By pressing&amp;nbsp;any of the&amp;nbsp;arrow buttons on your keyboard, Photoshop will automatically select the contents of the layer (does anybody know an easier way to do this?)...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop3.png" border="0" alt="Photoshop has Smart Selection" width="357" height="219" /&gt;&lt;/p&gt;&lt;p&gt;At this time we want the inverse of the current&amp;nbsp;selection&amp;nbsp;&amp;ndash;&amp;nbsp;the transparent part.&amp;nbsp;This can be accomplished easily by using&amp;nbsp;the keyboard shortcut Ctrl + Shift + I.&amp;nbsp;Here is the result...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop4.png" border="0" alt="Inverse of Previous Selection" width="357" height="219" /&gt;&lt;/p&gt;&lt;p&gt;Now we shall fill the transparent selection&amp;nbsp;with a solid white color. You could use a texture or a gradient here if you wanted to, but I am using plain old white. The keyboard shortcut for Fill is Shift + F5, and here is the result...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop5.png" border="0" alt="Result of Solid White Color Fill" width="357" height="219" /&gt;&lt;/p&gt;&lt;p&gt;After performing the Fill, the image looks like a solid white canvas. But we still have our selection, and we will want to inverse it again by pressing Ctrl + Shift + I. Then press delete to clear/erase the selection...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop6.png" border="0" alt="Result of Clearing the Inverse Selection" width="357" height="219" /&gt;&lt;/p&gt;&lt;p&gt;Press Ctrl + D to deselect and get a clearer view&amp;nbsp;of the image. Now it's time to add a slight Gaussian Blur to make the edges of our &amp;quot;cutout&amp;quot; nice and smooth...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop7.png" border="0" alt="Gaussian Blur Dialog Window" width="358" height="373" /&gt;&lt;/p&gt;&lt;p&gt;The wonderful PNG image format will allow the blur to accurately blend with anything behind it.&amp;nbsp;To save the image,&amp;nbsp;choose &amp;quot;Save for Web&amp;quot; from the File menu.&amp;nbsp;Be sure to&amp;nbsp;select PNG-24 image format&amp;nbsp;with transparency...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/photoshop8.png" border="0" alt="Save For Web - Image Format" width="266" height="213" /&gt;&lt;/p&gt;&lt;p&gt;Below&amp;nbsp;is the final result, with a two-pixel black&amp;nbsp;border added to it. As you can see, it blends in with the background perfectly...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/josh2.png" border="2" alt="Final Result, with a Border Added" width="200" height="90" /&gt;&lt;/p&gt;&lt;h3&gt;Utilizing&amp;nbsp;The Flexibility&lt;/h3&gt;&lt;p&gt;It is fairly easy to bring this into a web page and add a hover effect.&amp;nbsp;All you essentially need to do is apply&amp;nbsp;a background color to the image with CSS. I've setup a live demo page&amp;nbsp;which shows a few different&amp;nbsp;ways to implement this idea,&amp;nbsp;including some that use&amp;nbsp;SEO-friendly&amp;nbsp;&lt;a href="http://mezzoblue.com/tests/revised-image-replacement/" target="_blank" title="CSS Image Replacement"&gt;image replacement&lt;/a&gt;.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.josh420.com/examples/cutout/" title="Live Demo"&gt;View the Demo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.josh420.com/examples/cutout.zip" title="Download cutout.zip"&gt;Download&amp;nbsp;cutout.zip&lt;/a&gt; (7kb)&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;And that's all the time&amp;nbsp;I have today, folks. Please let me know if you found this useful.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=hl0o4Kg8xzw:XehXNBMIZbc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=hl0o4Kg8xzw:XehXNBMIZbc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=hl0o4Kg8xzw:XehXNBMIZbc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=hl0o4Kg8xzw:XehXNBMIZbc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=hl0o4Kg8xzw:XehXNBMIZbc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/06/cookie-cutter-image-hover-effect.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/06/cookie-cutter-image-hover-effect.aspx#comments</comments>
      <pubDate>Mon, 30 Jun 2008 22:49:12 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/06/cookie-cutter-image-hover-effect.aspx</guid>
      <category>CSS</category>
      <category>Standards</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments>
    </item>
    <item>
      <title>Consuming Web Services with DIME Attachments in VB.NET</title>
      <description>&lt;p&gt;In this post I will share a solution that I reached the other day regarding an InvalidOperationException that I was receiving when attempting to consume a SOAP web service with DIME attachments. Hopefully this will save you some time, as I was unable to find a good solution online when I encountered the error. DIME attachments are a Microsoft standard that has recently been deemed obsolete. Basically, it's a method of transmitting binary data via SOAP, in which the raw data is delivered &lt;em&gt;after&lt;/em&gt; the SOAP envelope. By keeping the data outside of the envelope, it does not have to be Base64 encoded (which would be required to keep the XML valid). Subsequently, the attachment does not have to be consumed by an XML parser on the client-side. This approach dramatically increases the performance of both the client and the server. Although effective, DIME has already been replaced by a newer standard called &lt;a href="http://www.w3.org/TR/soap12-mtom/" target="_blank" title="Message Transmission Optimization Mechanism"&gt;MTOM&lt;/a&gt;. However, DIME is still used today by several established APIs and will probably continue to be used unless an upgrade is absolutely warranted. To work with DIME attachments, Microsoft &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=8070E1DE-22E1-4C78-AB9F-07A7FCF1B6AA&amp;amp;displaylang=en" target="_blank" title="WSE 2.0"&gt;Web Service Enhancements 2.0&lt;/a&gt; will need to be used.&lt;/p&gt;&lt;p&gt;In my efforts to invoke the web service method and download an attachment, I constantly&amp;nbsp;received the following exception...&lt;/p&gt;&lt;dd&gt;&lt;p&gt;&lt;strong&gt;InvalidOperationException&lt;/strong&gt;: Client found response content type of 'application/dime', but expected 'text/xml'&lt;/p&gt;&lt;/dd&gt;&lt;p&gt;This was somewhat puzzling to me because I did not know what was forcing my client to expect &amp;quot;text/xml&amp;quot;. I was hoping there was a ContentType setting I could simply modify that would fix the error, but I was unable to find one. At this point, I was certain that the root of the issue was under the covers. In other words, it wasn't my code causing the problem, it had to be one of the underlying dependencies. So, I went ahead and did some digging into the MSDN documentation and found &lt;a href="http://msdn.microsoft.com/en-us/library/ms996944.aspx" target="_blank" title="MSDN Article"&gt;an article&lt;/a&gt; on the topic. One paragraph in particular grasped my attention, specifically the last sentence...&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;In order to use the WSE DIME support with a Microsoft .NET client application in Visual Studio, you must add a reference for the Microsoft.Web.Services2.dll assembly. Also, after adding a Web reference to the DIME-based Web service, &lt;strong&gt;you must modify the proxy class in the References.vb file so that it inherits from the Microsoft.Web.Services2.WebServicesClientProtocol class in WSE&lt;/strong&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Sweet! At this point, I thought I had this all figured out. Apparently, the exception I was receiving was caused by the proxy class that is automatically generated by ASP.NET. By default, this class inherits System.Web.Services.Protocols.SoapHttpClientProtocol. According to MSDN, this inheritance will not work with DIME attachments, so it needs to be changed to a class that comes with the WSE toolkit. By using Lutz Roeder's &lt;a href="http://www.aisto.com/roeder/dotnet/" target="_blank" title=".NET Reflector"&gt;Reflector&lt;/a&gt;, which is a wonderful tool, I verified that the only acceptable content types in the default proxy class are text/xml and application/soap+xml...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/reflector.png" border="0" alt="Disassembly in .NET Reflector" width="613" height="268" /&gt;&lt;/p&gt;&lt;p&gt;So that was definitely the problem. This glimmer of hope was shattered when I was completely unable to find the generated proxy class in my solution. Where on Earth is this References.vb file located?! It did not exist in my project because it was a &amp;quot;Web Site&amp;quot; project, and therefore the proxy class was being generated based on the WSDL and compiled on-the-fly by the web server. How do you modify code that is generated on-demand, behind the scenes, by ASP.NET? You don't. Damn!&lt;/p&gt;&lt;p&gt;This frustrated me quite a bit, especially since MSDN did not mention anything about my situation, which is one that I would consider to be common. What I ended up having to do was create a new class library with the sole purpose of invoking the web service. Then I replaced my web reference in the web site project with a reference to this new class libary. This theoretically simple process turned out to be a little confusing, so allow me to step you through it (note that I am using Visual Studio 2005). To begin, I added a new&amp;nbsp;Class Library project to the&amp;nbsp;current web site...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/menu.png" border="0" alt="File | Add New Project" width="384" height="492" /&gt;&lt;/p&gt;&lt;p&gt;As already mentioned, this class library will solely perform the task of invoking the web service.&amp;nbsp;So, the web reference needs to be removed from the web site project and then re-added to this new&amp;nbsp;class library. When you do this, Visual Studio will generate a proxy class for the service that you will be able to modify accordingly to prevent the InvalidOperationException from being thrown. Here is a screenshot illustrating where the proxy class is located in Solution Explorer...&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/06/solution.png" border="0" alt="Reference.vb in Solution Explorer" width="236" height="236" /&gt;&lt;/p&gt;&lt;p&gt;Open up the Reference.vb file (if you code in C# it will be called Reference.cs) so that you can modify the Inherits statement per MSDN's recommendation... &lt;/p&gt;&lt;div id="code8734" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; WebReferenceName

    &lt;span style="color: #0000ff"&gt;Partial&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; ServiceName
        &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; Microsoft.Web.Services2.WebServicesClientProtocol
        &lt;strike&gt;&lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; System.Web.Services.Protocols.SoapHttpClientProtocol
&lt;/strike&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;And that should be the only thing that needs changed. Prior to building, you may want to go into the class library configuration and set it to release mode so that debugging symbols are not generated. Once the library builds successfully, you will need to add a reference to it in your web site project. When you need to call the method that returns DIME attachments in your web site project, simply instantiate the web service within the class library like this...&lt;/p&gt;&lt;div id="code7684" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Service &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; MyClassLibrary.WebReferenceName.ServiceName()
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;This will prevent the InvalidOperationException from being thrown. Every time you update the web reference in the class library, you will have to go back in and change the inheritance of the proxy class again, which is pretty lame. Unfortunately, this is the best solution I was able to come up with. I hope somebody finds this helpful. If you have any questions or relevant insight, please leave a comment.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=MOPLwHj5a5U:61z873D1GCc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=MOPLwHj5a5U:61z873D1GCc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=MOPLwHj5a5U:61z873D1GCc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=MOPLwHj5a5U:61z873D1GCc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=MOPLwHj5a5U:61z873D1GCc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/06/consuming-web-services-with-dime-attachments-in-vbnet.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/06/consuming-web-services-with-dime-attachments-in-vbnet.aspx#comments</comments>
      <pubDate>Mon, 16 Jun 2008 14:38:19 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/06/consuming-web-services-with-dime-attachments-in-vbnet.aspx</guid>
      <category>ASP.NET</category>
      <category>VB.NET</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">7</slash:comments>
    </item>
    <item>
      <title>Support CSS Naked Day Redux</title>
      <description>&lt;p&gt;A couple days ago&amp;nbsp;I made a &lt;a href="http://blog.josh420.com/archives/2008/04/support-css-naked-day-easily-on-your-aspnet-web-site.aspx" title="A blog post from a few days ago"&gt;blog post&lt;/a&gt;&amp;nbsp;about&amp;nbsp;a simple HTTP handler written in ASP.NET.&amp;nbsp;The purpose?&amp;nbsp;To spit out 404 errors for .css file requests on CSS Naked Day.&amp;nbsp;That handler will undoubtedly work great, but it does have one minor maintenance-related flaw. Each year you will have to update the constant date value to be accurate. Granted, that is a simple task, but it still requires time and a little bit of effort. &lt;a href="http://blog.josh420.com/archives/2008/04/support-css-naked-day-easily-on-your-aspnet-web-site.aspx#comment1" title="Dustin Diaz's comment to the previous post"&gt;Dustin Diaz left a comment&lt;/a&gt; notifying me of a nice &lt;a href="http://php-naked-day-api.googlecode.com/files/config.json" target="_blank" title="JSON file on GoogleCode"&gt;JSON file&lt;/a&gt; sitting out on GoogleCode that I could tap into programmatically to determine the official date of CSS Naked Day.&amp;nbsp;And that&amp;nbsp;eliminates the maintenance flaw. Brilliant! So I went ahead and re-wrote the handler to call that JSON file and store the value in cache. There are some constant variables declared at the top that you can modify to your liking. Here is the code&amp;hellip;&lt;/p&gt;&lt;div id="code32151" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.IO
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Net
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Web
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Web.Caching

&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Naked
    &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler

    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; NAKED_DAY_API &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = &amp;quot;&lt;span style="color: #8b0000"&gt;http://php-naked-day-api.googlecode.com/files/config.json&lt;/span&gt;&amp;quot;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; NAKED_DAY_DEFAULT &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 9 &lt;span style="color: #008000"&gt;'The default day to use if the API call failed or was invalid (paranoia)&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; CACHE_KEY &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = &amp;quot;&lt;span style="color: #8b0000"&gt;Css.NakedDay&lt;/span&gt;&amp;quot;
    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; CACHE_LIFETIME &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 24 &lt;span style="color: #008000"&gt;'Number of hours to store the value in Cache&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; ProcessRequest(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; context &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Web.HttpContext) &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler.ProcessRequest
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Path &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = context.Request.PhysicalPath

        &lt;span style="color: #0000ff"&gt;With&lt;/span&gt; context.Response
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; File.Exists(Path) &lt;span style="color: #0000ff"&gt;AndAlso&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Today &amp;lt;&amp;gt; GetNakedDay(context.Cache) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                .ContentEncoding = Encoding.UTF8
                .ContentType = &amp;quot;&lt;span style="color: #8b0000"&gt;text/css&lt;/span&gt;&amp;quot;
                .WriteFile(Path, &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;)
            &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
                .StatusCode = 404
                .End()
                .Close()
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;With&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetNakedDay(&lt;span style="color: #0000ff"&gt;ByRef&lt;/span&gt; Cache &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Cache) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; MONTH &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 4
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; NakedDay &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Cache.Item(CACHE_KEY) &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Token &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Regex(&amp;quot;&lt;span style="color: #8b0000"&gt;&amp;quot;&amp;quot;day&amp;quot;&amp;quot; : (\d{1,2})&lt;/span&gt;&amp;quot;&lt;span style="color: #8b0000"&gt;)&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Api &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

            NakedDay = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Now.Year, MONTH, NAKED_DAY_DEFAULT)

            &lt;span style="color: #0000ff"&gt;Try&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Using&lt;/span&gt; Client &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; WebClient()
                    Api = Client.DownloadString(NAKED_DAY_API)
                &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Using&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Catch&lt;/span&gt; ex &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; WebException
                Api = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Try&lt;/span&gt;

            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.IsNullOrEmpty(Api) &lt;span style="color: #0000ff"&gt;AndAlso&lt;/span&gt; Token.IsMatch(Api) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Hold &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;() = Token.Matches(Api).Item(0).Value.Split(&amp;quot;&lt;span style="color: #8b0000"&gt;:&lt;/span&gt;&amp;quot;)
                NakedDay = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Now.Year, MONTH, &lt;span style="color: #0000ff"&gt;CInt&lt;/span&gt;(Hold(1).Trim()))

                &lt;span style="color: #008000"&gt;'Only add the value to cache if the API call was successful&lt;/span&gt;
                Cache.Add(CACHE_KEY, NakedDay, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Now.AddHours(CACHE_LIFETIME), Cache.NoSlidingExpiration, CacheItemPriority.Normal, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;)
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
            NakedDay = &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Parse(Cache.&lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;(CACHE_KEY))
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; NakedDay
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ReadOnly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; IsReusable() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler.IsReusable
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;To implement this handler into your ASP.NET web site, simply modify the &amp;lt;httpHandlers&amp;gt; element within &amp;lt;system.web&amp;gt; in the web.config file as illustrated here&amp;hellip; &lt;/p&gt;&lt;div id="code85157" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;verb&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;path&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;*.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Naked&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;validate&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;That's it. Enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=S6ITwNSN2Do:B5FQjGi8nJk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=S6ITwNSN2Do:B5FQjGi8nJk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=S6ITwNSN2Do:B5FQjGi8nJk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=S6ITwNSN2Do:B5FQjGi8nJk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=S6ITwNSN2Do:B5FQjGi8nJk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/04/support-css-naked-day-redux.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/04/support-css-naked-day-redux.aspx#comments</comments>
      <pubDate>Mon, 07 Apr 2008 21:59:53 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/04/support-css-naked-day-redux.aspx</guid>
      <category>ASP.NET</category>
      <category>CSS</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">4</slash:comments>
    </item>
    <item>
      <title>Support CSS Naked Day Easily on Your ASP.NET Web Site!</title>
      <description>&lt;p&gt;&lt;strong&gt;&lt;em&gt;UPDATE&lt;/em&gt;:&lt;/strong&gt; I have came up with &lt;a href="http://blog.josh420.com/archives/2008/04/support-css-naked-day-redux.aspx" title="Support CSS Naked Day Redux"&gt;a better zero-maintenance solution&lt;/a&gt; thanks to a comment by Dustin. The one bellow&amp;nbsp;will still work, you just have to maintain the date&amp;nbsp;constant that is defined at the top of the handler.&lt;/p&gt;&lt;p&gt;I kinda like the idea of &lt;a href="http://naked.dustindiaz.com/" target="_blank" title="CSS Naked Day!"&gt;CSS Naked Day&lt;/a&gt;, which was thought up by &lt;a href="http://www.dustindiaz.com/" target="_blank" title="Dustin Diaz"&gt;Dustin Diaz&lt;/a&gt; (a Google fellow) a couple of years ago. I have decided to participate. If you have a personal web site, I would encourage you to do the same. If your web site runs on ASP.NET (highly recommended), you can use the HTTP handler below. I wrote it today and am implementing on my blog. On CSS Naked Day, which is defined at the top of the handler in a constant, it will return a 404 HTTP status code for each and every request for a .css file. You just have to change this date every year and you'll be all set without having to modify any markup or move around files. Your blog engine might already have an HTTP handler setup to intercept .css file requests. If that is true, you can just reference my handler and modify your current one accordingly. Here is the code in VB.NET (attention crazy people: go &lt;a href="http://codechanger.com/" target="_blank" title="Code Converter by Telerik"&gt;here&lt;/a&gt; to convert to C#)&amp;hellip; &lt;/p&gt;&lt;div id="code74516" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.IO
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Web

&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Naked
    &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler

    &lt;span style="color: #0000ff"&gt;Const&lt;/span&gt; NAKED_DAY &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt; = #4/9/2008#

    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ReadOnly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; IsReusable() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler.IsReusable
        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; ProcessRequest(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; context &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Web.HttpContext) &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IHttpHandler.ProcessRequest
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Response &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; HttpResponse = context.Response
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Path &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = context.Request.PhysicalPath

        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; File.Exists(Path) &lt;span style="color: #0000ff"&gt;AndAlso&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;.Today &amp;lt;&amp;gt; NAKED_DAY &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            Response.ContentEncoding = Encoding.UTF8
            Response.ContentType = &amp;quot;&lt;span style="color: #8b0000"&gt;text/css&lt;/span&gt;&amp;quot;
            Response.WriteFile(Path, &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;)
        &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
            Response.StatusCode = 404
            Response.Close()
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;To implement this handler into your ASP.NET web site, simply modify the &amp;lt;httpHandlers&amp;gt; element within &amp;lt;system.web&amp;gt; as illustrated below&amp;hellip;&lt;/p&gt;&lt;div id="code6854" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;add&lt;/span&gt; &lt;span style="color: #ff0000"&gt;verb&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;*&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;path&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;*.css&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Naked&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;validate&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;false&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;httpHandlers&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Talk about easy! ASP.NET freakin' rules. It's uncomparable to&amp;nbsp;&lt;strong&gt;P&lt;/strong&gt;retty &lt;strong&gt;H&lt;/strong&gt;orrific &lt;strong&gt;P&lt;/strong&gt;rogramming, I can tell you that much.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=dOkaYMMtpLM:hRKcUjEeMCk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=dOkaYMMtpLM:hRKcUjEeMCk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=dOkaYMMtpLM:hRKcUjEeMCk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=dOkaYMMtpLM:hRKcUjEeMCk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=dOkaYMMtpLM:hRKcUjEeMCk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/04/support-css-naked-day-easily-on-your-aspnet-web-site.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/04/support-css-naked-day-easily-on-your-aspnet-web-site.aspx#comments</comments>
      <pubDate>Sat, 05 Apr 2008 19:14:56 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/04/support-css-naked-day-easily-on-your-aspnet-web-site.aspx</guid>
      <category>ASP.NET</category>
      <category>CSS</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments>
    </item>
    <item>
      <title>Opening External Links in a New Window Based on User Preference</title>
      <description>&lt;p&gt;I spend alot of time surfing the Internet. Who doesn't? When I come across an outgoing link (when I say outgoing, I mean a link to a page that resides on a different domain), I always have to make a decision. As an end user, I am clueless as to whether or not the link will open up in a new window. Perhaps the browser is to blame for this. Regardless, I don't usually take any chances, so I right-click the link and choose to open it in a new window/tab. Every potentially suspicious link (most of them are) requires at least two clicks. I have reached the point that I do this instictively, without even thinking about it. I honestly feel the browser should be responsible for telling the user which links will be opened externally, and perhaps there should also be settings in place for the user to specify how they want &lt;em&gt;all&lt;/em&gt; links to behave, depending on anchor tag attributes such as target=&amp;quot;_blank&amp;quot; and rel=&amp;quot;external&amp;quot;. It doesn't take long before you realize that waiting for browsers to do what you want is a lost cause, no matter what religion you are or how often you pray. So, I took action. I came up with a Javascript solution that puts the choice in the user's hands.&lt;/p&gt;&lt;p&gt;In my opinion, an ideal solution would be to setup a link/button/checkbox/whatever on your site that, when the user clicks it, will execute some Javascript to force all external links to be opened in a new window. On top of that, the users preference should be &amp;quot;remembered&amp;quot; by storing it in a cookie. You might have seen &lt;a href="http://jinabolton.com/" target="_blank" title="Jina Bolton has this feature on her site"&gt;something&lt;/a&gt; like &lt;a href="http://yesterdayishere.com/wordpress/" target="_blank" title="Bojan Janjanin also has this feature"&gt;this&lt;/a&gt; before. I think this is a pretty damn user-friendly approach. In light of that, I have prepared an elegant script that performs the duty, and is quite simple to implement and extend. Before getting to the juicy code, allow me to explain how it works.&lt;/p&gt;&lt;h3&gt;Nuts and Bolts, Baby! &lt;/h3&gt;&lt;p&gt;When the web page loads, my script will look for the existence of a cookie. The cookie it's looking for will be one that the same set of Javascript previously created. If it finds it, it will loop through the links accordingly and attach an onclick event handler to open the HREF in a new window (or tab, depending on how your browser settings are configured). If it does not find the cookie, it does nothing. So users without the cookie will have the default link behavior; the target attribute of the links will still be effective. You, the developer of the web site, are responsible for coming up with a stylish link/button/checkbox for the user to make their selection. All you have to do is call a Javascript function when the user clicks this element, with one boolean parameter, and that's it. The rest is done for you. Passing true to the function will make all outgoing links open in a new window. Passing false will make them all open in the same window. This function sets the cookie and loops through every &amp;lt;a&amp;gt; tag on the page. If the HREF attribute points to an external web site, it will be opened in a new window when clicked (if the boolean parameter was true). It's a relatively simple concept, right? Turning concept into code is not as simple. Luckily for you, I've got it all taken care of.&lt;/p&gt;&lt;p&gt;I created an unobtrusive object model that is straight-forward and is nice and simple to use. Most importantly, you can add the feature to an existing site pretty easily. I have tested the code in all major popular browsers as of today (April 2, 2008), and it worked great in all of them. If you have any questions on how to modify this script to your liking, don't hesitate to ask. Here is the Javascript code&amp;hellip;&lt;/p&gt;&lt;div id="code93621" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; addLoadEvent(func) {
  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt; &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.onload != '&lt;span style="color: #8b0000"&gt;function&lt;/span&gt;')
    &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.onload = func;
  &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(func) {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; oldLoad = &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.onload;

      &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.onload = &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(oldLoad) oldLoad();
        func();
      }
    }
  }
}

&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; Links = {
  IsCapable: (&lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementsByTagName),
  CookieId: '&lt;span style="color: #8b0000"&gt;MyLinkCookie&lt;/span&gt;',
  GetCookie: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; vals = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.cookie.split('&lt;span style="color: #8b0000"&gt;;&lt;/span&gt;');

    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; i = 0; i &amp;lt; vals.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;; i++) {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; val = vals[i].replace(/^\s+/, '');

      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(val.indexOf(Links.CookieId) == 0)
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; val.substring(Links.CookieId.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt; + 1, val.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;);
    }

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;
  },
  SetCookie: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(bool) {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; dat = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Date&lt;/span&gt;();
    dat.setTime(dat.getTime() + 63072000000); &lt;span style="color: #008000"&gt;//2 years&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; val = Links.CookieId + '&lt;span style="color: #8b0000"&gt;=&lt;/span&gt;' + bool;
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; exp = '&lt;span style="color: #8b0000"&gt;; expires=&lt;/span&gt;' + dat.toGMTString();
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; path = '&lt;span style="color: #8b0000"&gt;; path=/&lt;/span&gt;';

    &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.cookie = val + exp + path;
  },
  RemoveCookie: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.cookie = Links.CookieId + '&lt;span style="color: #8b0000"&gt;=false; expires=Fri, 02-Jan-1970 00:00:00 GMT; path=/&lt;/span&gt;';
  },
  SetExternals: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(bool) {
    Links.SetCookie(bool);
    Links.Scan();
  },
  Scan: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; bool = Links.GetCookie();

    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(!Links.IsCapable || !bool)
      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;

    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; links = &lt;span style="color: #0000ff"&gt;document&lt;/span&gt;.getElementsByTagName('&lt;span style="color: #8b0000"&gt;a&lt;/span&gt;');

    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; i = 0; i &amp;lt; links.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;; i++) {
      &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; href = links[i].getAttribute('&lt;span style="color: #8b0000"&gt;href&lt;/span&gt;');

      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(href.substring(0, 5) == '&lt;span style="color: #8b0000"&gt;http:&lt;/span&gt;' || href.substring(0, 6) == '&lt;span style="color: #8b0000"&gt;https:&lt;/span&gt;') {
        &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; pageUrl = &lt;span style="color: #0000ff"&gt;location&lt;/span&gt;.protocol + '&lt;span style="color: #8b0000"&gt;//&lt;/span&gt;' + &lt;span style="color: #0000ff"&gt;location&lt;/span&gt;.host;

        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(href.substring(0, pageUrl.&lt;span style="color: #0000ff"&gt;length&lt;/span&gt;) != pageUrl) {
          &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(bool == '&lt;span style="color: #8b0000"&gt;true&lt;/span&gt;') {
            links[i].onclick = &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {
              &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; winId = '&lt;span style="color: #8b0000"&gt;win&lt;/span&gt;' + &lt;span style="color: #0000ff"&gt;Math&lt;/span&gt;.random().&lt;span style="color: #0000ff"&gt;toString&lt;/span&gt;().substring(2);
              &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; newWin = &lt;span style="color: #0000ff"&gt;window&lt;/span&gt;.&lt;span style="color: #0000ff"&gt;open&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.href, winId);
              newWin.&lt;span style="color: #0000ff"&gt;focus&lt;/span&gt;();
              &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
            }
          }
          &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
            links[i].onclick = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

          links[i].removeAttribute('&lt;span style="color: #8b0000"&gt;target&lt;/span&gt;');
        }
      }
    }    
  }
}

addLoadEvent(Links.Scan);
&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;Uhhhh, How Do I Use This Code?&lt;/h3&gt;&lt;p&gt;I won't leave you hangin' with just a chunk of Javascript; I have setup a &lt;a href="http://blog.josh420.com/examples/ExternalLinks/" target="_blank" title="Demonstrational Page"&gt;demo&lt;/a&gt; page illustrating the functionality. It&amp;nbsp;is simple, really. All you have to do is bring in the script into your page (with &amp;lt;script&amp;gt; tags, respectively). There are two main functions: Links.SetExternals and Links.RemoveCookie. SetExternals is the function I mentioned earlier that expects the boolean parameter. Calling the RemoveCookie function will essentially return link behavior to the default. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blog.josh420.com/examples/ExternalLinks/" target="_blank" title="View the Demo"&gt;View the Demo&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.josh420.com/examples/ExternalLinks.zip" title="Download the Code"&gt;Download the Code&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The demo uses standard hyperlinks to set the preference, but I think a checkbox is probably the most practical thing to use here, which can be done rather&amp;nbsp;easily just&amp;nbsp;like this...&lt;/p&gt;&lt;div id="code50055" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;checkbox&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Links.SetExternals(this.checked);&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;So go ahead, make your visitors happy by giving them a useful option. If you have any problems using this script, or any relevant questions, feel free to &lt;a href="http://blog.josh420.com/archives/2008/04/opening-external-links-in-new-window-based-on-user-preference.aspx#comment" title="Contribute your thoughts"&gt;express yourself&lt;/a&gt;. That's all folks, enjoy!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=zhp0gaH6bFI:CRahBQ41Ax4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=zhp0gaH6bFI:CRahBQ41Ax4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=zhp0gaH6bFI:CRahBQ41Ax4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=zhp0gaH6bFI:CRahBQ41Ax4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=zhp0gaH6bFI:CRahBQ41Ax4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/04/opening-external-links-in-new-window-based-on-user-preference.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/04/opening-external-links-in-new-window-based-on-user-preference.aspx#comments</comments>
      <pubDate>Fri, 04 Apr 2008 18:03:39 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/04/opening-external-links-in-new-window-based-on-user-preference.aspx</guid>
      <category>Javascript</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">7</slash:comments>
    </item>
    <item>
      <title>Scott Guthrie Used to be an Actor!</title>
      <description>&lt;p&gt;So&amp;hellip; I was watching&amp;nbsp;a&amp;nbsp;classic film called &lt;a href="http://www.imdb.com/title/tt0115683/" target="_blank" title="Bio-Dome"&gt;Bio-Dome&lt;/a&gt; today, and I couldn't help but notice that&amp;nbsp;an actor in that film looks &lt;em&gt;exactly&lt;/em&gt; like &lt;a href="http://weblogs.asp.net/scottgu" target="_blank" title="Scott Guthrie"&gt;Scott Guthrie&lt;/a&gt;!&amp;nbsp;I was expecting this&amp;nbsp;feller to start yip-yapping about the glorious benefits of ASP.NET,&amp;nbsp;but then&amp;nbsp;I realized that I was &lt;strong&gt;not&lt;/strong&gt; watching a podcast&amp;hellip;&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/03/scottgu_biodome.png" border="0" alt="Scott Guthrie Look-Alike Playing in the Movie Bio-Dome" width="523" height="334" /&gt;&lt;/p&gt;&lt;p&gt;That screenshot is&amp;nbsp;at about 13:38 into the movie. Am I crazy, or does this guy look exactly like ScottGu?! Alright, so the real Scott isn't &lt;em&gt;that&lt;/em&gt; bald, but still.&amp;nbsp;This guy could show up at a&amp;nbsp;developers conference and get&amp;nbsp;numerous hand-shakes from people he doesn't know.&lt;/p&gt;&lt;p&gt;For the instinctively curious, this actor's real&amp;nbsp;name is &lt;a href="http://www.imdb.com/name/nm0922182/" target="_blank" title="Kevin West"&gt;Kevin West&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=6xITOjbZRSg:tV3vU8FJviI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=6xITOjbZRSg:tV3vU8FJviI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=6xITOjbZRSg:tV3vU8FJviI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=6xITOjbZRSg:tV3vU8FJviI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=6xITOjbZRSg:tV3vU8FJviI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/03/scott-guthrie-used-to-be-an-actor.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/03/scott-guthrie-used-to-be-an-actor.aspx#comments</comments>
      <pubDate>Sat, 08 Mar 2008 20:13:25 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/03/scott-guthrie-used-to-be-an-actor.aspx</guid>
      <category>Stuff</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments>
    </item>
    <item>
      <title>Twitter Sucks!</title>
      <description>&lt;p&gt;I decided to sign up for Twitter the other night for no reason at all.&amp;nbsp;&lt;a href="https://twitter.com/JoshStodola" target="_blank" title="My Tweets"&gt;I have used it a few times&lt;/a&gt; since then, and I can appreciate the whole social networking aspect of it.&amp;nbsp;However,&amp;nbsp;I can't help but&amp;nbsp;conclude that&amp;nbsp;this the most idiotic&amp;nbsp;thing that&amp;nbsp;I have ever signed up for. I just don't understand the purpose of writing several short messages throughout the day.&amp;nbsp;Are you going to return several months later to see what you did&amp;nbsp;on Feburary 28th?&amp;nbsp;Oh, and it's totally unstable and slower than molasses! After Googling about it, I noticed on Wikipedia that it is written in Ruby on Rails. LMAO!&amp;nbsp;That explains why the site is down RIGHT NOW!&lt;/p&gt;&lt;p&gt;Another thing worth mentioning is the poor site design.&amp;nbsp;It literally took me&amp;nbsp;four or&amp;nbsp;five clicks just to locate a textbox that I can enter a name to search. When I naturally&amp;nbsp;click &amp;quot;Find &amp;amp; Follow&amp;quot;, this is the crap I am greeted with&amp;hellip;&lt;/p&gt;&lt;p class="img"&gt;&lt;img src="http://blog.josh420.com/images/2008/02/twitter_blows.jpg" border="0" alt="Worthless page, courtesy of Twitter" width="814" height="712" /&gt;&lt;/p&gt;&lt;p&gt;I don't have Hotmail or Yahoo or Gmail or AOL or MSN. Even if I did, I probably would not be giving up the password. So I have one other option: send an email invitation. WTF?! How about a textbox to enter a name, and when I press a button, you look in your database of users for a match and display the results to me as soon as possible. Wow, that would be amazingly brilliant for a page with a title of &amp;quot;Find People You Know on Twitter&amp;quot;.&lt;/p&gt;&lt;p&gt;I am sure this service&amp;nbsp;gets most of its usage&amp;nbsp;via mobile phones, 3rd party applications&amp;nbsp;and what-not, but c'mon, the web interface should be usable as well.&amp;nbsp;After all, is that not the &amp;quot;roots&amp;quot; of the application?&lt;/p&gt;&lt;p&gt;I gotta say that Twitter and Gravatar give me horrible impressions of Ruby on Rails. I think the word I am looking for is scalability.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=-GfUXLxG26k:osmlbHOFtfU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=-GfUXLxG26k:osmlbHOFtfU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=-GfUXLxG26k:osmlbHOFtfU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=-GfUXLxG26k:osmlbHOFtfU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=-GfUXLxG26k:osmlbHOFtfU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/02/twitter-sucks.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/02/twitter-sucks.aspx#comments</comments>
      <pubDate>Thu, 28 Feb 2008 22:59:34 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/02/twitter-sucks.aspx</guid>
      <category>Rants</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">31</slash:comments>
    </item>
    <item>
      <title>The Underlying Connection was Closed - How to Fix This Pesky ASP.NET WebException</title>
      <description>&lt;p&gt;If your ASP.NET application calls&amp;nbsp;a web service (you have a reference in your App_WebReferences folder), you might come across this fairly typical System.Net.WebException. I have seen two different&amp;nbsp;breeds of this exception, and the solutions for each of them are quite&amp;nbsp;similiar. I will start off with the most common of the two.&lt;/p&gt;&lt;h3&gt;The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.&lt;/h3&gt;&lt;p&gt;This is the one you are most likely to see, and the fix for this is simple and generally well-known. You&amp;nbsp;need to create a class that inherits your web service class. Then you simply override the GetWebRequest function and modify the KeepAlive HTTP header accordingly&amp;hellip; &lt;/p&gt;&lt;div id="code79132" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; MyWebService
    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; ServiceName.WebService

    &lt;span style="color: #0000ff"&gt;Protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Overrides&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetWebRequest(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; uri &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Uri) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Net.WebRequest
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; webRequest &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Net.HttpWebRequest = &lt;span style="color: #0000ff"&gt;MyBase&lt;/span&gt;.GetWebRequest(uri)

        webRequest.KeepAlive = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; webRequest
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Simple as that. When you need to invoke the web service elsewhere in your code, just instatiate &lt;em&gt;that&lt;/em&gt; class instead of what you would do normally&amp;hellip;&lt;/p&gt;&lt;div id="code83752" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; Response &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Using&lt;/span&gt; MyService &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; MyWebService()
    Response = MyService.METHOD_NAME(&amp;quot;&lt;span style="color: #8b0000"&gt;MethodInput&lt;/span&gt;&amp;quot;)
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Using&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;And that takes care of that exception.&lt;/p&gt;&lt;h3&gt;The underlying connection was closed: The connection was closed unexpectedly.&lt;/h3&gt;&lt;p&gt;Sometimes, using the solution above will &lt;em&gt;cause&lt;/em&gt; this exception. I believe that it has something to do with the way Windows Authentication is configured in IIS. I ran across a situation where I had to deploy my applicaton (with web service references) to a remote server that was not in our control; it was being hosted for us. Apparently, they were using &lt;a href="http://www.innovation.ch/personal/ronald/ntlm.html" target="_blank" title="NTLM Authentication Scheme for HTTP"&gt;NTLM Authentication&lt;/a&gt;, which requires connections to be kept-alive, hence this exception. However, using KeepAlive makes your requests totally inconsistent, in most cases. They will work one time, but will fail the next. The host was not willing to change for this for our application, obviously, so I was stuck. Finally, I was able to determine that the ConnectionGroupName property is what is used to re-establish the connection that was supposed to be &amp;quot;kept alive&amp;quot;. So, you can just set that property to a random value (GUID), in the same way that I set the KeepAlive property above&amp;hellip; &lt;/p&gt;&lt;div id="code99450" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; MyWebService
    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; ServiceName.WebService

    &lt;span style="color: #0000ff"&gt;Protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Overrides&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetWebRequest(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; uri &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Uri) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Net.WebRequest
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; webRequest &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.Net.HttpWebRequest = &lt;span style="color: #0000ff"&gt;MyBase&lt;/span&gt;.GetWebRequest(uri)

        webRequest.ConnectionGroupName = Guid.NewGuid().ToString()

        &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; webRequest
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;Problem solved; that worked fantastic! I hope this has helped you out, and I also hope that I have had my final bout with the System.Net.WebException.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=v40dROVY_lc:TxViH3_RxL8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=v40dROVY_lc:TxViH3_RxL8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=v40dROVY_lc:TxViH3_RxL8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=v40dROVY_lc:TxViH3_RxL8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=v40dROVY_lc:TxViH3_RxL8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/02/underlying-connection-closed-fix-pesky-aspnet-webexception.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/02/underlying-connection-closed-fix-pesky-aspnet-webexception.aspx#comments</comments>
      <pubDate>Sat, 16 Feb 2008 00:51:52 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/02/underlying-connection-closed-fix-pesky-aspnet-webexception.aspx</guid>
      <category>ASP.NET</category>
      <category>VB.NET</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">12</slash:comments>
    </item>
    <item>
      <title>Creating a "Save As..." Button for the Rendered Markup of an ASP.NET Page</title>
      <description>&lt;p&gt;I am not sure why you would want to do this, but I have seen&amp;nbsp;the question asked&amp;nbsp;on the &lt;a href="http://forums.asp.net/" target="_blank" title="ASP.NET forums"&gt;ASP.NET forums&lt;/a&gt; a couple of times so I figured I would post a solution for it.&amp;nbsp;It is not that difficult to&amp;nbsp;create a &amp;quot;Save As&amp;hellip;&amp;quot; button on your web page that, when clicked, will prompt the user with a download dialog&amp;nbsp;containing the rendered markup of the page.&amp;nbsp;All you have to do is have a button that will refresh the page, except append a query string to it.&amp;nbsp;Then in the Page_Load you can check for the existence of the&amp;nbsp;query string and change the content type and disposition of the response to trigger the dialog.&lt;/p&gt;&lt;p&gt;First, add the following markup where you want it on your page&amp;hellip; &lt;/p&gt;&lt;div id="code4744" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;button&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Save Page As&amp;hellip;&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;onclick&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;(location.href.indexOf('?') == -1) ? location.href += '?save=true' : location.href += '&amp;amp;save=true';&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;All that is doing is adding a query string to the existing URL and redirecting to it. Add this code in the Page_Load to check for the query string and do the necessary steps to force the download prompt&amp;hellip; &lt;/p&gt;&lt;div id="code90946" class="code"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Request.QueryString.Item(&amp;quot;&lt;span style="color: #8b0000"&gt;save&lt;/span&gt;&amp;quot;) &lt;span style="color: #0000ff"&gt;IsNot&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Request.QueryString.Item(&amp;quot;&lt;span style="color: #8b0000"&gt;save&lt;/span&gt;&amp;quot;).ToString() = &amp;quot;&lt;span style="color: #8b0000"&gt;true&lt;/span&gt;&amp;quot; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        Response.Clear()
        Response.ContentEncoding = Encoding.UTF8
        Response.ContentType = &amp;quot;&lt;span style="color: #8b0000"&gt;text/plain&lt;/span&gt;&amp;quot;
        Response.AddHeader(&amp;quot;&lt;span style="color: #8b0000"&gt;content-disposition&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;attachment&lt;/span&gt;&amp;quot;)
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;And that is all there is to it! This could easily be wrapped up in an ASP.NET&amp;nbsp;User Control so that it could be dropped into&amp;nbsp;several&amp;nbsp;different pages&amp;nbsp;effortlessly. Again, I am not sure why you would want to do this. To me, this is the same as&amp;nbsp;manually viewing the page source and saving it to your hard drive. Oh well, I hope somebody out there finds it useful.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;UPDATED&lt;/strong&gt; 02/03/2008: Shortened onclick event handler for the button.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=54DEla-rqU0:4ZPjQg-AmgE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=54DEla-rqU0:4ZPjQg-AmgE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=54DEla-rqU0:4ZPjQg-AmgE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/JoshStodola?a=54DEla-rqU0:4ZPjQg-AmgE:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/JoshStodola?i=54DEla-rqU0:4ZPjQg-AmgE:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://blog.josh420.com/archives/2008/02/creating-save-as-button-for-the-rendered-markup-of-an-aspnet-page.aspx</link>
      <author>Josh Stodola - josh420@josh420.com</author>
      <comments>http://blog.josh420.com/archives/2008/02/creating-save-as-button-for-the-rendered-markup-of-an-aspnet-page.aspx#comments</comments>
      <pubDate>Sat, 02 Feb 2008 16:51:11 -0600</pubDate>
      <guid isPermaLink="true">http://blog.josh420.com/archives/2008/02/creating-save-as-button-for-the-rendered-markup-of-an-aspnet-page.aspx</guid>
      <category>ASP.NET</category>
      <category>Stuff</category>
      <slash:comments xmlns:slash="http://purl.org/rss/1.0/modules/slash/">3</slash:comments>
    </item>
  </channel>
</rss>
