<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-23184915</id><updated>2011-04-21T17:18:55.230-07:00</updated><category term='linux'/><category term='quote'/><category term='XmlReader'/><category term='facebook'/><category term='hack-a-thon'/><category term='Ubuntu'/><category term='introduction'/><category term='workaholics'/><title type='text'>Microsoft.Net | C# | ASP.Net</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23184915.post-972341006785331084</id><published>2007-06-15T08:10:00.000-07:00</published><updated>2007-06-16T08:19:14.968-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><category scheme='http://www.blogger.com/atom/ns#' term='XmlReader'/><title type='text'>SimpleXmlParser</title><content type='html'>&lt;p&gt;For the recent Facebook platform integration project I was tasked with parsing various forms of Xml returned from the Facebook REST web service.  REST or Representational State Transfer, is a term coined by Roy Fielding in his Ph.D. dissertation to describe an architecture style of networked systems.  In the Facebook world, to get back some data from there servers you make a POST to a specific PHP page (&lt;a href="http://api.facebook.com/restserver.php"&gt;http://api.facebook.com/restserver.php&lt;/a&gt;).  The results are returned as an Xml document.  In PHP there is a library called SimpleXmlParser which can be used to parses a XML file into a data structure.  In the Microsoft.NET world we have the XmlReader class which provides forward-only, read-only access to a stream of XML data. In .Net the XmlReader is the most memory efficient approach to parsing an Xml structure. Unfortunately, those of us who choose to use this class know the level of frustration one will experience when asked to parse an Xml document which contain variable node names.   &lt;/p&gt;
&lt;pre&gt;
&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;query&amp;gt;
  &amp;lt;session&amp;gt;2222222222&amp;lt;/session&amp;gt;
  &amp;lt;users list="true"&amp;gt;
    &amp;lt;user&amp;gt;
      &amp;lt;uid&amp;gt;10000001&amp;lt;/uid&amp;gt;
      &amp;lt;name&amp;gt;Person 1&amp;lt;/name&amp;gt;
    &amp;lt;/user&amp;gt;
    &amp;lt;user&amp;gt;
      &amp;lt;uid&amp;gt;10000002&amp;lt;/uid&amp;gt;
      &amp;lt;name&amp;gt;Person 2&amp;lt;/name&amp;gt;
    &amp;lt;/user&amp;gt;
 &amp;lt;/users&amp;gt;
&amp;lt;/query&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Examining the Xml arrangement we quickly see a pattern to how we might construct a data structure that would ease our ability to access specific keys within the information.  The following is how I would like to parse the Xml data and access the list of users.&lt;/p&gt;
&lt;pre&gt;
SimpleXmlResponse xml = 
      SimpleXmlParser.Parse(xmlString, "uid");
SimpleXmlList list = xml["users"] as SimpleXmlList;

---structure---
xml  Count = 2  SimpleXmlResponse
 [0] {[session, 2222222222]}  KeyValuePair&lt;string,object&gt;
    Key  "session" string
    Value "2222222222"  object {string}
 [1] {[users, SimpleXmlList]}  KeyValuePair&lt;string,object&gt;
    Key  "users" string
    Value Count = 2  object {SimpleXmlList}
    [0]  {[10000001, SimpleXmlItem]} KeyValuePair&lt;string,SimpleXmlItem&gt;
      Key "10000001" string
      Value  Count = 2  SimpleXmlItem
        [0] {[uid, 10000001]} KeyValuePair&lt;string,string&gt;
        [1] {[name, Person 1]}  KeyValuePair&lt;string,string&gt;
    [1] {[10000002, SimpleXmlItem]} KeyValuePair&lt;string,SimpleXmlItem&gt;
      Key "10000002" string
      Value Count = 2 SimpleXmlItem
        [0] {[uid, 10000002]} KeyValuePair&lt;string,string&gt;
        [1] {[name, Person 2]}  KeyValuePair&lt;string,string&gt;
&lt;/pre&gt;
&lt;p&gt;
Here are a few things to note:
&lt;ul&gt;
&lt;li&gt;The three objects listed above (SimpleXmlResponse, SimpleXmlList, SimpleXmlItem) are nothing more than classes that inherit from System.Collections.Generic.Dictionary.  There purpose is to ease readability and facilitate the casting of the result data.&lt;/li&gt;
&lt;li&gt;Since SimpleXmlResponse has a value which might contain either a string or a SimpleXmlList, we store this value as an object.  This data type will require us to cast the value to string for simple nodes.&lt;/li&gt;
&lt;li&gt;Each child node contained within those elements flagged as lists (list attribute = true) will have more than one value key pair.  As  a result, we must either assume the first element is distinct and can be used as the key for the SimpleXmlList element, or we must explicitly identify which element is distinct.
 &lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Code:&lt;/strong&gt;&lt;/br&gt;
&lt;textarea rows="10" cols="40" READONLY&gt;
using System;
using System.Xml;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace Terralever.Facebook
{
    public class SimpleXmlParser
    {
        public static SimpleXmlResponse Parse(string xml)
        {
            return Parse(xml, string.Empty);
        }
        public static SimpleXmlResponse Parse(string xml, string listKeyName)
        {
            SimpleXmlResponse response = new SimpleXmlResponse();
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            using (XmlReader reader = XmlReader.Create(new StringReader(xml), settings))
            {
                reader.MoveToContent();
                while (reader.NodeType != XmlNodeType.EndElement &amp;&amp; !reader.EOF)
                {
                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        if (reader.GetAttribute("list") != null)
                            response.Add(reader.Name, ParseList(reader.Name, reader, listKeyName));
                        else
                        {
                            string rootName = reader.Name;
                            reader.ReadStartElement(rootName);

                            if (reader.Name.Length &lt;= 0)
                                response.Add(rootName, reader.ReadString());
                            else
                                response.Add(reader.Name, reader.ReadString());

                            reader.ReadEndElement();
                        }
                    }
                    else
                        reader.Skip();
                    reader.MoveToContent();
                }
            }
            return response;
        }
        private static SimpleXmlList ParseList(string nodeName, XmlReader reader, string pkName)
        {
            bool isEmpty = reader.IsEmptyElement;
            string keyValue = string.Empty;

            SimpleXmlList response = new SimpleXmlList();
            SimpleXmlItem item = new SimpleXmlItem();

            int startDepth = reader.Depth;
            reader.ReadStartElement(nodeName);

            while (!reader.LocalName.Equals(nodeName))
            {
                int depth = reader.Depth;

                if ((depth == startDepth + 1) &amp;&amp; reader.NodeType == XmlNodeType.Element)
                {
                    item = new SimpleXmlItem();
                    reader.Read();
                }
                else if ((depth == startDepth + 1) &amp;&amp; reader.NodeType == XmlNodeType.EndElement)
                {
                    if (!response.ContainsKey(keyValue))
                        response.Add(keyValue, item);

                    keyValue = string.Empty;
                    reader.Read();
                }
                else if ((depth == startDepth + 2))
                {
                    string key = reader.Name;
                    string value = reader.ReadElementString();
                    //if the pkName was not specified then we will assume the first element is unique and can be used as the key
                    if ((keyValue.Length &lt;= 0) || key.Equals(pkName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        keyValue = value;
                    }
                    if (!item.ContainsKey(key))
                        item.Add(key, value);
                }
                else
                    reader.Read();
            }
            reader.ReadEndElement();
            return response;
        }
    }
    public class SimpleXmlResponse : Dictionary&lt;string, object&gt;
    {

    }
    public class SimpleXmlList : Dictionary&lt;string, SimpleXmlItem&gt;
    {

    }
    public class SimpleXmlItem : Dictionary&lt;string, string&gt;
    {

    }
}
&lt;/textarea&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-972341006785331084?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/972341006785331084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=972341006785331084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/972341006785331084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/972341006785331084'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/06/simplexmlparser.html' title='SimpleXmlParser'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-2813340898328951596</id><published>2007-06-07T10:28:00.001-07:00</published><updated>2007-06-07T13:00:43.213-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='Ubuntu'/><title type='text'>Ubuntu saves the day!</title><content type='html'>&lt;a href="http://www.ubuntu.com/"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_vlvDPobDYss/RmhA2iF6vQI/AAAAAAAAAIo/nUmQmrCpKsg/s200/ubuntulogo.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5073376285841603842" /&gt;&lt;/a&gt;Last night I was tasked with extracting some data from an unbootable Windows XP desktop. Now I know there is hardware out there that would have allowed me to pull the hard drive and mount it on another PC, but my goal was to mount the computer from a bootable CD or USB drive. What I hoped would be a fairly easy thing, turned out to be so painful that I opted for a simpler approach. 

Let me start off by apologizing to the Windows gods because my solution involved &lt;strong&gt;Open Source&lt;/strong&gt; a copy of &lt;strong&gt;Ubuntu 7.04&lt;/strong&gt;. You heard me correct....an open source Linux based operating system was used to save my XP data.

It was a really sad evening to realize that it took me longer to read the instruction on how I MIGHT be able to create a Vista boot disk, then it did to download the 650mb ISO, burn it on to a cd, boot to Linux, open up a NTFS partition and copy 4GB of data to my local NAS.

I love Microsoft.NET, but there is something special about a fully functional OS that fits on a single CD!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-2813340898328951596?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/2813340898328951596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=2813340898328951596' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/2813340898328951596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/2813340898328951596'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/06/ubuntu-saves-day.html' title='Ubuntu saves the day!'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_vlvDPobDYss/RmhA2iF6vQI/AAAAAAAAAIo/nUmQmrCpKsg/s72-c/ubuntulogo.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-7813331974114157478</id><published>2007-05-24T17:59:00.000-07:00</published><updated>2007-05-24T18:44:28.413-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='facebook'/><title type='text'>Live from the Facebook f8 launch</title><content type='html'>&lt;a href="http://3.bp.blogspot.com/_vlvDPobDYss/RlY4jWrNjvI/AAAAAAAAAIg/uoOJW0Uwkf0/s1600-h/facebook-f8-746900.gif"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_vlvDPobDYss/RlY4jWrNjvI/AAAAAAAAAIg/uoOJW0Uwkf0/s200/facebook-f8-746900.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5068300610685472498" /&gt;&lt;/a&gt;Its official, today in San Fransisco Facebook launched it new Facebook platform. This Platform is a development system that enables companies and developers to build applications that directly integrate into the Facebook website.

For about two weeks now, a team of overworked developers from &lt;a href="http://www.terralever.com"&gt;Terralever&lt;/a&gt; have been secretly burning the midnight oil, learning, leveraging and developing two applications for this new and exciting Facebook platform.

Let me be the first to say that this was an exciting opportunity for Terralever. As one of the only Interactive development firms asked to participate, we had a great opportunity to learn the platform, which will certainly be leveraged by thousands of company in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-7813331974114157478?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/7813331974114157478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=7813331974114157478' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7813331974114157478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7813331974114157478'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/05/facebook-launches-f8.html' title='Live from the Facebook f8 launch'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_vlvDPobDYss/RlY4jWrNjvI/AAAAAAAAAIg/uoOJW0Uwkf0/s72-c/facebook-f8-746900.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-7831873438720289172</id><published>2007-05-04T10:06:00.001-07:00</published><updated>2007-05-04T10:06:46.016-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><title type='text'>Quote of the Day</title><content type='html'>"There are two ways of constructing a software design. One way is to make it so simple that there are obviously no deficiencies. And the other way is to make it so complicated that there are no obvious deficiencies."
—C.A.R. Hoare&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-7831873438720289172?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/7831873438720289172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=7831873438720289172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7831873438720289172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7831873438720289172'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/05/quote-of-day.html' title='Quote of the Day'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-2542475342319019637</id><published>2007-04-30T12:29:00.000-07:00</published><updated>2007-04-30T12:44:42.416-07:00</updated><title type='text'>Unexpectedly foiled</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_vlvDPobDYss/RjZD7uX7tAI/AAAAAAAAAD4/EceSgDLbaUs/s1600-h/143.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_vlvDPobDYss/RjZD7uX7tAI/AAAAAAAAAD4/EceSgDLbaUs/s200/143.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5059305924737086466" /&gt;&lt;/a&gt;Have you ever wondered how a team of extremely creative people might join together and express themselves? Take one vacationing coworker like myself, combine it with a few boxes of tinfoil and you get the funniest prank I have ever been on the receiving end of.
&lt;br style="clear:both"/&gt;&lt;a href="http://4.bp.blogspot.com/_vlvDPobDYss/RjZD8OX7tBI/AAAAAAAAAEA/EZaxt4Bprsk/s1600-h/144.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_vlvDPobDYss/RjZD8OX7tBI/AAAAAAAAAEA/EZaxt4Bprsk/s200/144.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5059305933327021074" /&gt;&lt;/a&gt;&lt;a href="http://2.bp.blogspot.com/_vlvDPobDYss/RjZD8uX7tCI/AAAAAAAAAEI/_-Rd5Fu0ZHg/s1600-h/145.JPG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_vlvDPobDYss/RjZD8uX7tCI/AAAAAAAAAEI/_-Rd5Fu0ZHg/s200/145.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5059305941916955682" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-2542475342319019637?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/2542475342319019637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=2542475342319019637' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/2542475342319019637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/2542475342319019637'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/04/unexpectedly-foiled.html' title='Unexpectedly foiled'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_vlvDPobDYss/RjZD7uX7tAI/AAAAAAAAAD4/EceSgDLbaUs/s72-c/143.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-9034143793909803018</id><published>2007-04-19T08:02:00.000-07:00</published><updated>2007-06-16T08:41:12.734-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='workaholics'/><title type='text'>"The Red Zone"</title><content type='html'>&lt;p&gt;How much work is too much?&lt;/p&gt;  
&lt;p&gt;In the May 2007 issue of &lt;a href="http://www.fastcompany.com/magazine/115/indexerror.html"&gt;Fast Company &lt;/a&gt;magazine there is an interesting article by Joe Robinson titled "The Red Zone".  The premise of the article is that every company has those employees that repeatedly work 60+ hours a week and a common misconception is that these "workaholics" are some form of a corporate "hero".   Contrary to what some employees believe, excessive hours is a red flag and should be considered an indication of possible productivity issues. Not only dedication and work ethic.    The article talks about flagging these type of employee if the behavior become excessive and repetitive, and put  in place a constructive plan to increase their productivity while reducing their hours.
&lt;/p&gt;
&lt;p&gt;
I honestly could not agree more with this article.  I think that many companies lose sight of the relationship between quality productivity and dedication.  All of us cherish  a dedicated employee, but are these type of employees really fulfilled.  We all have at least one coworker that you know will do whatever it takes to get a project completed.  I respect that passion, but after about 14 hours sitting in front of a computer the quality of code a developer produces diminishes.  A career is not a sprint but a very long marathon.  We as managers need to look at excessive hours as a sign of hidden efficiency  issues such as unrealistic timelines, scope creep or even external  personal issues.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-9034143793909803018?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/9034143793909803018/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=9034143793909803018' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/9034143793909803018'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/9034143793909803018'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/04/red-zone.html' title='&quot;The Red Zone&quot;'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-5841076615916418571</id><published>2007-04-16T06:51:00.000-07:00</published><updated>2007-06-16T08:40:18.158-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hack-a-thon'/><title type='text'>hack-a-thon 2007</title><content type='html'>&lt;p&gt;Wikipedia defines a “hack-a-thon” as an event where programmers meet to do collaborative computer programming.  An event where a group of people meet at a specific time to “hack” on what they want to, how they want to - with little to no restrictions on direction or goal of the programming.  (http://en.wikipedia.org/wiki/Hackathon)
&lt;/p&gt;
&lt;p&gt;
This begs the question, could the idea of a “hack-a-thon” be repurposed to crank out a professional web site in less than a day?  
&lt;/p&gt;
&lt;p&gt;
Last Thursday Terralever gave it a shot, and held the first Annual “Terralever.com  Hack-a-thon”.  The goal was to take a new Terralever.com creative design, and give it life between 4PM Thursday and 6AM Friday morning.  All this after a full day of work.  Equipped with some creative comps, 20 egger employees,  and a ton of Redbull, we set out  to test all of our skills, expertise and ultimately our focus.
&lt;/p&gt;
&lt;p&gt;
I would love to say that we made our goal, but at about 5AM it became evident that as hard as we had worked, we just would never have the  whole site complete by 6AM. 
&lt;/p&gt;
&lt;p&gt;
So did we fail…hardly!  Success was not about getting to the finish, but about the journey to get there. I have been in development for quite some time and never embarked on such a challenge.  It was exhausting, but a whole lot of fun.  I was extremely impresses by how focused and driven the entire development team was throughout the whole night.  There was a great balance between having fun and working hard. There is no question that by 5AM most if not everyone was mentally fried, but no one gave up, everyone was still focused on completing there tasks. 
&lt;/p&gt;
&lt;p&gt;
It is not fair to measure this experience solely on success or failure, but if a complete site was our goal, there are certainly things we can learn from this experience.  I my opinion it all came down to better planning.  Timeline, IA and design comps are essential but just not enough.  The best chance we had at completing this task was to make a more formal script of who was going to complete what, and in what sequence.  All design should have been formalized prior to the event. 
&lt;/p&gt;
&lt;p&gt;
When we attempt this challenge again (and I hope we do) we need to have designed the entire data model, object model and site architecture as part of preparation.  On Thursday development spent the first 2 hours just thinking about how we would store and deliver data to the end user. This time investment was necessary to get started, but irreplaceable by early morning.  Decisions we made the day of the event had a direct effect on the order we should have cut up the site, prepared copy and integrated interactive with development.  In the future, every employee needed a clear understanding of what individual tasks they would be assigned, giving them an opportunity to better research solutions and look for existing code to leverage during the event.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-5841076615916418571?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/5841076615916418571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=5841076615916418571' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/5841076615916418571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/5841076615916418571'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/04/hack-thon-2007.html' title='hack-a-thon 2007'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-7592741214760019972</id><published>2007-03-29T17:10:00.000-07:00</published><updated>2007-03-29T17:30:35.424-07:00</updated><title type='text'>&lt;compilation batch="false"&gt;</title><content type='html'>Today some of the C# / ASP.NET 2.0 code I created generated the following error &lt;strong&gt;"Circular file references are not allowed"&lt;/strong&gt;.  

After quite a bit of investigation, I realized that this was the result of how I had User Control’s organized within my website.  For no good reason I was separating many of my user controls into sub directories within a parent "Controls" directory.

&lt;blockquote&gt;C:\....
  +---Controls
    +----- Admin
    +----- Resources&lt;/blockquote&gt;
By default, the compiler will batch assemblies (usually one per folder). This resulted in all files in the "Admin" folders being built into single assembly, while all files in the "Controls" folder where built into another.

In my situation I had a control in the root (Controls) referencing a control in "Admin", while another control in "Admin" referenced one in "Controls".

To temporarily get past the compiler issue one can set the batch attribute in the compilation element of the webconfig equal to false. (&lt;compilation batch="false"&gt;)  This tells the ASP.NET compiler to not batch assemblies, and instead create an assembly for each user control.  Now obviously this is not a good idea in production, but is a great way to get past the error in testing.

The long term solution is to remove the additional sub directories or better organize them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-7592741214760019972?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/7592741214760019972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=7592741214760019972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7592741214760019972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7592741214760019972'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/03/today-some-of-c-asp.html' title='&amp;lt;compilation batch=&quot;false&quot;&amp;gt;'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-4367926605736464949</id><published>2007-03-29T08:26:00.000-07:00</published><updated>2007-03-29T08:30:16.874-07:00</updated><title type='text'>Apollo</title><content type='html'>Check out this new product from Adobe Labs. It's a cross-operating system runtime being developed that allows developers to leverage Flash, Flex, HTML, JavaScript, and Ajax to build and deploy rich Internet applications (RIAs) to the desktop.

&lt;a href="http://labs.adobe.com/technologies/apollo/"&gt;http://labs.adobe.com/technologies/apollo/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-4367926605736464949?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/4367926605736464949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=4367926605736464949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/4367926605736464949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/4367926605736464949'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/03/apollo.html' title='Apollo'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-1605680964480330859</id><published>2007-03-24T12:52:00.000-07:00</published><updated>2007-06-16T08:38:22.865-07:00</updated><title type='text'>URL Redirection with Mod-Rewrite ISAPI filter</title><content type='html'>&lt;p&gt;Recently, one of our clients required that there entire site be optimized for search engines. As part of SEO our goal was to create hackable URL's and avoid special characters on the query string. This meant no querystring arguments. We choose to use URL rewriting as a way to map dynamic virtual directories to database content.&lt;/p&gt;
&lt;p&gt;
Our goal was to take a friendly URL like below, and remap them to a more typical aspx page with arguments.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Input:&lt;/em&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;span style="font-size:85%;"&gt;http://www.client.com/news/press/200703/aquisition&lt;/span&gt;&lt;/strong&gt;
&lt;strong&gt;&lt;em&gt;Output:
&lt;/em&gt;&lt;span style="font-size:85%;"&gt;http://www.client.com/article.aspx?sectionid=22&amp;issue=200703&amp;amp;name=acquisition&lt;/span&gt;&lt;/strong&gt;
&lt;/P&gt;
&lt;p&gt;
For the most part, URL rewriting in ASP.NET 2.0 is pretty straight forward. You create a class that implements System.Web.IHttpModule and register that class as a &lt;httpmodules&gt;in the webconfig. All requests made to .aspx pages run through the handler prior to being redirected.&lt;br/&gt;

Unfortunately our goal for a friendly URL desired no file or extension, resulting in an interesting issue. Unless we placed a default.aspx page within each physical directory, the request would never fire through the ASP.NET process. Interestingly, ASP does not require this for the root of the site or once you hit 4 directories deep. In both of those situations, asp assumes default.aspx exists, resulting in the HtppModule firing.
&lt;/P&gt;
&lt;p&gt;
&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/br&gt;
Our solution was to use a a free ISAPI filter called mod_rewrite (&lt;a href="http://www.iismods.com/download.htm"&gt;http://www.iismods.com/download.htm&lt;/a&gt;). This filter will allow us to append default.aspx to any requests that did not include a file with extension.&lt;br/&gt;

This filter is quite easy to use, it is completely configured via an INI file that uses regular expressions combined with back referencing to apply the rewrite. The following is the INI file we use to match requests with both a trailing slash "/" and without.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;span style="font-size:85%;"&gt;mod_rewrite.ini&lt;/span&gt;&lt;/strong&gt;&lt;br/&gt;
&lt;blockquote&gt;Debug 1
Reload 2000
#Browse LOT
RewriteRule ^([^.]+)/([^/.]+)$ $1/$2/default.aspx
RewriteRule ^([^.]+)/$ $1/default.aspx&lt;/blockquote&gt;&lt;br/&gt;
We have yet to test this under high load, but expect its performance to be adequate since it excludes everything but the page request.&lt;strong&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-1605680964480330859?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/1605680964480330859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=1605680964480330859' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/1605680964480330859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/1605680964480330859'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/03/url-redirection-with-mod-rewrite-isapi.html' title='URL Redirection with Mod-Rewrite ISAPI filter'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-7711869080396307840</id><published>2007-03-21T22:17:00.000-07:00</published><updated>2007-03-22T10:26:46.813-07:00</updated><title type='text'>Loading custom web control from an .aspx Code-Behind page</title><content type='html'>Yesterday one of our clients requested a simple change to a custom user control for one of their ASP.NET 2.0 site. We made the change, and deployed ONLY the .ascx file to their production server.

The deployment resulted in the following run-time error:

&lt;strong&gt;Unable to cast object of type 'ASP.controls_customControl_ascx' to type 'controls_customControl’. &lt;/strong&gt;

This error appeared to disappear by editing the webconfig file.

The structure of the control we edited was such that it dynamically loaded a second control in its code behind. This was done by making a reference to the custom control through the use of the @Register directive in the .ascx page.

&lt;strong&gt;&amp;lt%@ Register Src="customControl.ascx" TagName="CustomControl" TagPrefix="uc1" %&amp;gt&lt;/strong&gt;

In the code behind, the control was then loaded and explicitly cast to the appropriate type upon the click of a button in the control.

&lt;strong&gt;controls_customControl custom = (controls_customControl)LoadControl("../controls/customControl.ascx");&lt;/strong&gt;
(NOTE: The dynamically loaded control inherits from a class defined in a precompiled assembly)

&lt;strong&gt;So what happen?&lt;/strong&gt;

We all know that when the first request arrives for any page within a folder ASP.NET dynamically parses and compiles all the ASPX pages in that folder. We also know that it compiles any code-behind files associated with ASCX files into a separate assembly. If two pages exist in the same folder they will be compiled into the same assembly. Based on this understanding, I would have predicted that the file being changed would have been enough to trigger a recompile of the control folders assembly, eliminating the error.

&lt;strong&gt;Could the behavior come as a result of the @Register directive?&lt;/strong&gt;

When you load a control programmatically the strong type for the control is available only after you have created a reference to it. By definition @Register is used for declarative inclusion of control in a page. The assembly referenced in the directive is dynamically created the first time the ASP.NET runtime accesses the resource. The instance of the control will be created “on-the-fly” when the page is loaded.

It has always been my understanding that when a programmer chooses to load a control in the code-behind, the strong type of the control is only available after the page has made reference to it, making @Register inappropriate. Without the implicit inclusion of the control in the page, the compiler should throw and error. I believe in our situation it worked because both controls exist in the same directory resulting in them being compiled into the same assembly.

Most documentation suggests that one should use the @Reference directive and NOT @Register when loading controls programmatically. @Reference tells .NET that the referenced control MUST be dynamically compiled and linked. If two controls in the same directory have dependencies on each other through an @Reference directive, they will end up in separate assemblies.

Would this have eliminated my error…time to do some testing!

&lt;strong&gt;….to be continued….&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-7711869080396307840?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/7711869080396307840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=7711869080396307840' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7711869080396307840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/7711869080396307840'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/03/loading-custom-web-control-from-aspx.html' title='Loading custom web control from an .aspx Code-Behind page'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23184915.post-1480894530103455621</id><published>2007-03-20T21:52:00.000-07:00</published><updated>2007-03-21T06:41:38.536-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='introduction'/><title type='text'>Introduction</title><content type='html'>My name is Joel, and I am a Microsoft.NET system architect and Director of Development for a leading interactive development firm located in Tempe, Arizona. Our firm designs and develops a wide range of custom web applications which leverage Flash, Ajax, ASP.NET and the Microsoft.Net Framework.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23184915-1480894530103455621?l=neubeck.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://neubeck.blogspot.com/feeds/1480894530103455621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23184915&amp;postID=1480894530103455621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/1480894530103455621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23184915/posts/default/1480894530103455621'/><link rel='alternate' type='text/html' href='http://neubeck.blogspot.com/2007/03/introduction.html' title='Introduction'/><author><name>joel</name><uri>http://www.blogger.com/profile/10536929898794013921</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
