<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" version="2.0">
    <channel>
        <title>you've been HAACKED</title>
        <link>http://haacked.com/Default.aspx</link>
        <description>...and you like it.</description>
        <language>en-US</language>
        <copyright>Haacked</copyright>
        <generator>Subtext Version 2.0.1.2</generator>
        <image>
            <title>you've been HAACKED</title>
            <url>http://haacked.com/images/RSS2Image.gif</url>
            <link>http://haacked.com/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <geo:lat>34.03056</geo:lat><geo:long>-118.398043</geo:long><creativeCommons:license>http://creativecommons.org/licenses/by-sa/2.5/</creativeCommons:license><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/haacked" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">haacked</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
            <title>The Law of Demeter Is Not A Dot Counting Exercise</title>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx</link>
            <description>&lt;p&gt;Recently I read a discussion on an internal mailing list on whether or not it would be worthwhile to add a null dereferencing operator to C#.&lt;/p&gt;  &lt;p&gt;For example, one proposed idea would allow the following expression.&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;object&lt;/span&gt; a = foo.?bar.?baz.?qux;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;This would assign the variable &lt;code&gt;a&lt;/code&gt; the value &lt;code&gt;null&lt;/code&gt; if any one of &lt;code&gt;foo,&lt;/code&gt; &lt;code&gt;bar&lt;/code&gt;, or &lt;code&gt;baz&lt;/code&gt; is null &lt;em&gt;instead of &lt;/em&gt;throwing a &lt;code&gt;NullReferenceException&lt;/code&gt;. It’s a small, but potentially helpful, mitigation for the &lt;a title="The Billion Dollar Mistake" href="http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake"&gt;billion dollar mistake&lt;/a&gt;.&lt;/p&gt;

&lt;p class="clear"&gt;Sure enough, it did not take long for someone to claim that this syntax would be unnecessary if the code here was not violating the sacred &lt;a title="Law of Demeter" href="http://en.wikipedia.org/wiki/Law_of_Demeter"&gt;Law of Demeter&lt;/a&gt; (or LoD for short). I think this phenomena is an analog to &lt;a title="Godwin's Law" href="http://en.wikipedia.org/wiki/Godwin's_law"&gt;Godwin’s Law&lt;/a&gt; and deserves its own name. Let’s call it the “LoD Dot Counting Law”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p class="clear"&gt;As a discussion of a code expression with more than one dot grows longer, the probability that someone claims a Law of Demeter violation approaches 1.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p class="clear"&gt;&lt;a title="Count the dots and win a prize! By acme on Flickr - CC By Attribution" href="http://www.flickr.com/photos/acme/2571866655/"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="dippindots" border="0" alt="dippindots" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/dc0335001dbb_9404/dippindots_3.jpg" width="554" height="416" /&gt;&lt;/a&gt; &lt;em class="caption"&gt;Count the dots and win a prize!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;What is wrong with the claim that the above expression violates LoD? To answer that let’s briefly cover the Law of Demeter. I’m not going to cover it in detail but rather point to posts that describe it in much better detail than I would.&lt;/p&gt;

&lt;h3&gt;The Many Forms of Demeter&lt;/h3&gt;

&lt;p&gt;The &lt;a title="Object form of LOD" href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/object-formulation.html"&gt;formal object form&lt;/a&gt; of the law can be summarized as:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;A method of an object may only call methods of:&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;The object itself. &lt;/li&gt;

    &lt;li&gt;An argument of the method. &lt;/li&gt;

    &lt;li&gt;Any object created within the method. &lt;/li&gt;

    &lt;li&gt;Any direct properties/fields of the object. &lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;A &lt;a title="General formulation" href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html"&gt;general formulation of the law&lt;/a&gt; is:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.&lt;font style="background-color: #ffffff" size="3" face="Trebuchet MS"&gt; Or: Each unit should only talk to its friends; Don’t talk to strangers.&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p class="clear"&gt;This of course leads to the succinct form of the law:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p class="clear"&gt;&lt;font style="background-color: #ffffff" size="3" face="Trebuchet MS"&gt;Don’t talk to strangers&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In other words, try to avoid calling methods of an object that was returned by calling another method. Often, people shorten the law to simply state “&lt;em&gt;use only one dot&lt;/em&gt;”.&lt;/p&gt;

&lt;p&gt;One of the key benefits of applying LoD is low coupling via encapsulation. In his paper, &lt;a title="The Paperboy, The Wallet, and The Law of Demeter" href="http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf"&gt;The Paperboy, The Wallet, and The Law of Demeter (PDF)&lt;/a&gt; (it’s a relatively quick read so go ahead, I’ll be here), David Bock provides a great illustration of this law with an analogy of a paperboy and a customer. Rather than having a customer hand over his wallet to pay the paperboy, he instead has the paperboy request payment from the customer.&lt;/p&gt;

&lt;p&gt;In answer to “Why is this better?” David Bock gives these three reasons.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The first reason that this is better is because it better models the real world scenario...  The Paperboy code is now 'asking' the customer for a payment.  The paperboy does not have direct access to the wallet.   &lt;/p&gt;

  &lt;p&gt;The second reason that this is better is because the Wallet class can now change, and the paperboy is completely isolated from that change…&lt;/p&gt;

  &lt;p&gt;The third, and probably most 'object-oriented' answer is that we are now free to change the implementation of 'getPayment()'.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Note that the first benefit is an improvement not only in encapsulation but the abstraction is also improved.&lt;/p&gt;

&lt;h3&gt;Dot Counting Is Not The Point&lt;/h3&gt;

&lt;p&gt;You’ll note that David doesn’t list “50% less dots in your code!” as a benefit of applying LoD. The focus is on reduced coupling and improved encapsulation.&lt;/p&gt;

&lt;p&gt;So going back to the initial expression, does &lt;code&gt;foo.bar.baz.qux&lt;/code&gt; violate LoD? Like most things, it depends.&lt;/p&gt;

&lt;p&gt;For example, suppose that &lt;code&gt;foo&lt;/code&gt; is of type &lt;code&gt;Something&lt;/code&gt; and it contains properties named &lt;code&gt;Bar&lt;/code&gt;, &lt;code&gt;Baz&lt;/code&gt;, and &lt;code&gt;Qux&lt;/code&gt; which each simply return &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this semi-contrived example, the expression is not an LoD violation because each property returns the object itself and according to the first rule of LoD, “you do not talk about LoD” … wait … sorry… “a method is free to call any properties of the object itself” (in a future post, I will cover the &lt;em&gt;class&lt;/em&gt; form of LoD which seems to indicate that if &lt;code&gt;Bar&lt;/code&gt;, &lt;code&gt;Baz&lt;/code&gt;, and &lt;code&gt;Qux&lt;/code&gt; return the same type, whether it’s the same object or not, LoD is preserved).&lt;/p&gt;

&lt;p&gt;This pattern is actually quite common with fluent interfaces where each method in a calling chain might return the object itself, but transformed in some way.&lt;/p&gt;

&lt;p&gt;So we see that counting dots is not enough to indicate an LoD violation. But lets dig deeper. Are there other cases where counting dots leads do not indicate an LoD violation? More importantly, is it always a bad thing to violate LoD? Are there cases where an LoD violation might even be the right thing to do?&lt;/p&gt;

&lt;h3&gt;Go Directly to Jail, Do Not Pass Go&lt;/h3&gt;

&lt;p&gt;Despite its name, violating the Law of Demeter will not get you on an episode of Cops nor is it some inviolable law of nature.&lt;/p&gt;

&lt;p&gt;As the &lt;a title="Assuring Good Style for Object-Oriented Programs" href="http://labs.cs.utt.ro/labs/ip2/html/resources/Lieberherr-LawOfDemeter.pdf"&gt;original paper points out&lt;/a&gt;, it was developed during design and implementation of the Demeter system (hence the name) and was held to be a law for the developers of &lt;em&gt;that system&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The designers of the system felt that this practice ensured good Object-Oriented design:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The motivation behind the Law of Demeter is to ensure that the software is as modular as possible. The law effectively reduces the occurrences of nested message sendings (function calls) and simplifies the methods.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, while it was a law in the context of the Demeter system, whether it should hold the weight that calling it a &lt;em&gt;Law&lt;/em&gt; implies is open to debate.&lt;/p&gt;

&lt;p&gt;David Bock refers to it as an idiom:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;This paper is going to talk about a particluar &lt;em&gt;(sic)&lt;/em&gt; 'trick' I like, one that is probably better classified as an 'idiom' than a design pattern (although it is a component in many different design patterns).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;a title="Martin Fowler on Twitter" href="http://twitter.com/martinfowler/status/1649793241"&gt;Martin Fowler suggests&lt;/a&gt; (emphasis mine)&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I'd prefer it to be called the &lt;em&gt;Occasionally Useful Suggestion of Demeter&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Personally, I think most developers are guilty of bad encapsulation and tight coupling. I’m a bit more worried about that than applying this law inappropriately (though I worry about that too). Those who have deep understanding of this guideline are the ones who are likely to know when it shouldn’t be applied.&lt;/p&gt;

&lt;p&gt;For the rest of us mere mortals, I think it’s important to at least think about this guideline and be intentional about applying or not applying it.&lt;/p&gt;

&lt;h3&gt;I Fought The Law and The Law Won&lt;/h3&gt;

&lt;p&gt;So what are the occasions when the Law of Demeter doesn’t necessarily apply? There’s some debate out there on the issue.&lt;/p&gt;

&lt;p&gt;In his post, &lt;a title="Misunderstanding the Law of Demeter" href="http://www.dcmanges.com/blog/37"&gt;Misunderstanding the Law of Demeter&lt;/a&gt;, Daniel Manges argues that web page views aren’t domain objects and thus shouldn’t be subject to the Law of Demeter. His argument hinges on a Rails example where you send an &lt;code&gt;Order&lt;/code&gt; object to the view, but the view needs to display the customer’s name.&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= @order.customer.name &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Counting two dots, he considers the change that would make it fit LoD:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= @order.customer_name &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;He then asks:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Why should an order have a customer_name? We're working with objects, an order should have a customer who has a name.&lt;/p&gt;

  &lt;p&gt;…when rendering a view, it's natural and expected that the view needs to branch out into the domain model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Alex Blabs of Pivotal Labs &lt;a title="Lovely Demeter, Meter Maid" href="http://pivotallabs.com/users/alex/blog/articles/273-lovely-demeter-meter-maid"&gt;takes issue with Daniel’s post and argues&lt;/a&gt; that views &lt;em&gt;are &lt;/em&gt;domain objects and an order ought to have a &lt;code&gt;customer_name&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;It’s an interesting argument, but the &lt;a title="Comment" href="http://pivotallabs.com/users/alex/blog/articles/273-lovely-demeter-meter-maid#459"&gt;following snippet of a comment&lt;/a&gt; by Zak Tamsen summarizes where I currently am on this subject (though my mind is open).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;because they don't. the primary job of the views (under discussion) is to expose the internal state of objects for display purposes. that is, they are expressly for data showing, not data hiding. and there's the rub: these kind of views flagrantly violate encapsulation, LoD is all about encapsulation, and no amount of attribute delegation can reconcile this.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem as I see it with Alex’s approach is where do you stop? Does the &lt;code&gt;Order&lt;/code&gt; object encapsulate every property of &lt;code&gt;Customer&lt;/code&gt;? What about sub-properties of the &lt;code&gt;Customer&lt;/code&gt;’s properties? It seems the decision to encapsulate the Customer’s name is driven by the view’s need to display it. I wouldn’t want my domain object’s interface to be driven by the needs of the view as that would violate separation of concerns.&lt;/p&gt;

&lt;p&gt;There’s another option which might be more common in the &lt;a title="ASP.NET Website" href="http://asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; world than in the Rails world, I’m not sure. Why not have a view specific model object. This would effectively be the bridge between the domain objects and the view and could encapsulate many of the these properties that the view needs to display.&lt;/p&gt;

&lt;p&gt;Another case where an LoD violation might not be such a bad idea is in cases where the object structure is public and unlikely to change. While in Norway, I had the opportunity to briefly chat with &lt;a title="Michael Feathers Blog" href="http://blog.objectmentor.com/articles/category/michaels-musings"&gt;Michael Feathers&lt;/a&gt; about LoD and he pointed out the example of Excel’s object model for tables and cells. If LoD is about encapsulation (aka information hiding) then why would you hide the structure of an object where the structure is exactly what people are interested in and unlikely to change?&lt;/p&gt;

&lt;h3&gt;Use It or Lose It&lt;/h3&gt;

&lt;p&gt;When I learn a new guideline or principle, I really like to dig into where the guideline breaks down. Knowing where a guideline works, and what its advantages are is only half the story in really understanding it. When I can explain where it doesn’t work and what its disadvantages are, only then do I feel I’m starting to gain understanding.&lt;/p&gt;

&lt;p&gt;However, in writing about my attempts at understanding, it may come across that I’m being critical of the guideline. I want to be clear that I think the Law of Demeter is a very useful guideline and it applies in more cases than not. It’s one of the few principles that can point to an empirical study that may point to its efficacy.&lt;/p&gt;

&lt;p&gt;In a &lt;a title="Paper on OO design metrics" href="http://www.cs.umd.edu/users/basili/publications/journals/J62.pdf"&gt;Validation of Object-Oriented Design Metrics as Quality Indicators&lt;/a&gt;, the authors of the study provide evidence that suggests The Law of Demeter reduces the probability of software faults.&lt;/p&gt;

&lt;p&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="the-count" border="0" alt="the-count" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/dc0335001dbb_9404/the-count_3.jpg" width="404" height="270" /&gt; Still, I would hope that those who apply it don’t do it blindly by counting dots. Dot counting can help you find where to look for violations, but always keep in mind that the end goal is reducing coupling, not dots.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f383d6d7-fd32-41fb-8766-cbb47ca9cb27" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/SOLID" rel="tag"&gt;SOLID&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Software+Development" rel="tag"&gt;Software Development&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Patterns" rel="tag"&gt;Patterns&lt;/a&gt;,&lt;a href="http://technorati.com/tags/Law+of+Demeter" rel="tag"&gt;Law of Demeter&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18628.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=L9aFHqqeIA0:_-FeDe7hIcw:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=L9aFHqqeIA0:_-FeDe7hIcw:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=L9aFHqqeIA0:_-FeDe7hIcw:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=L9aFHqqeIA0:_-FeDe7hIcw:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=L9aFHqqeIA0:_-FeDe7hIcw:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx</guid>
            <pubDate>Tue, 14 Jul 2009 17:48:29 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18628.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx#feedback</comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18628.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Geek Your Momma Jokes</title>
            <category>Humor</category>
            <link>http://haacked.com/archive/2009/07/08/geek-your-momma-jokes.aspx</link>
            <description>&lt;p&gt;Ok, I haven’t had a good track record with making up jokes before. Just see exhibit A -&lt;a href="http://haacked.com/archive/2008/01/29/so-a-model-a-view-and-a-controller-walk-into.aspx"&gt; this groaner of an MVC joke&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;However, I think I did okay recently with a few geeky Your Momma jokes that I can’t just leave to Twitter alone. Here they are:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Your momma so fat, Bloatware is her clothing line.&lt;/p&gt;    &lt;p&gt;Your momma so fat I called her and got a stack overflow.&lt;/p&gt;    &lt;p&gt;your momma so ugly its just best to forego the "V" in MVC with her.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So now it’s your turn. Please post your best ones in the comments to this post. :)&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f3d87b69-7d2a-49c8-9e8b-387d58e4af34" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/humor" rel="tag"&gt;humor&lt;/a&gt;,&lt;a href="http://technorati.com/tags/jokes" rel="tag"&gt;jokes&lt;/a&gt;,&lt;a href="http://technorati.com/tags/your+momma+jokes" rel="tag"&gt;your momma jokes&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18627.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DbOOr0SU3EM:Lx9uxwj-oqk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=DbOOr0SU3EM:Lx9uxwj-oqk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DbOOr0SU3EM:Lx9uxwj-oqk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=DbOOr0SU3EM:Lx9uxwj-oqk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=DbOOr0SU3EM:Lx9uxwj-oqk:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/07/08/geek-your-momma-jokes.aspx</guid>
            <pubDate>Wed, 08 Jul 2009 21:52:14 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18627.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/07/08/geek-your-momma-jokes.aspx#feedback</comments>
            <slash:comments>81</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18627.aspx</wfw:commentRss>
        </item>
        <item>
            <title>NDC09 Trip Report</title>
            <category>Personal</category>
            <category>Software Development</category>
            <category>ASP.NET</category>
            <category>ASP.NET MVC</category>
            <link>http://haacked.com/archive/2009/06/28/ndc2009-trip-report.aspx</link>
            <description>&lt;p&gt;When you visit Norway, it takes a week to recover. Ok, at least when &lt;em&gt;I&lt;/em&gt; visit Norway, it takes a week. But that’s just a testament to the good time I had. As they say, what happens in Vegas stays in Vegas, but what happens in Oslo gets &lt;a title=".NET Rocks Live with Hanselman and Haack" href="http://www.dotnetrocks.com/default.aspx?showNum=458"&gt;recorded as a .NET Rocks Live episode&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The week before last, I spent the week in Oslo, Norway attending and speaking at the &lt;a title="NDC 2009" href="http://www.ndc2009.no/en/"&gt;Norwegian Developer’s Conference&lt;/a&gt; (NDC 09). This conference was not your typical Microsoft conference I usually attend but was a conference on .NET with a heavy Agile Software bent.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3460.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="IMG_3460" border="0" alt="IMG_3460" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3460_thumb.jpg" width="544" height="409" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Just looking at the &lt;a title="Speaker Lineup" href="http://www.ndc2009.no/en/index.aspx?cat=1070"&gt;speaker line-up&lt;/a&gt; will tell you that. &lt;a title="Scott Bellware's Blog" href="http://blog.scottbellware.com/" rel="friend met"&gt;Scott Bellware&lt;/a&gt; &lt;a title="Bellware on Twitter" href="http://twitter.com/bellware/status/2332327295"&gt;tweeted a blurb&lt;/a&gt; recently that succinctly summarized my impression of the conference:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;how to know you're at a good conference: the speakers are going to sessions (at least the ones who aren't working on their sessions)&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;That is definitely true. I didn’t attend as many talks as I would have liked, but I did manage to attend two by &lt;a title="Mary Poppendieck" href="http://www.poppendieck.com/"&gt;Mary Poppendieck&lt;/a&gt; which really sparked my imagination and got me excited about the concept of a problem solving organization and learning more about Lean. She had promised to put her slides on her site, but I can’t for the life of me find them! ;)&lt;/p&gt;  &lt;p&gt;While there, I gave three talks, one of them being a joint talk with the &lt;a title="Scott Hanselman's Blog" href="http://hanselman.com/" rel="friend met co-worker"&gt;Hanselnator&lt;/a&gt; (aka Mr. Hanselman).&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;strong&gt;Black Belt Ninja Tips &lt;a title="ASP.NET Website" href="http://asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;This covered several tips on getting more out of ASP.NET MVC and included the first public demonstration of &lt;a href="http://blogs.msdn.com/davidebb/archive/2009/06/17/a-new-and-improved-asp-net-mvc-t4-template.aspx"&gt;David Ebbo’s T4 template&lt;/a&gt;.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;ASP.NET MVC + AJAX = meant for each other        &lt;br /&gt;&lt;/strong&gt;This covered the Ajax helpers included with ASP.NET MVC and drilled into some of the lesser known client aspects of these helpers, such as showing the &lt;code&gt;Sys.Mvc.AjaxContext&lt;/code&gt; object and how to leverage it. The talk then moved into a demonstration of the client templating feature of &lt;a title="Preview 4 of Ajax 4" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24645"&gt;ASP.NET Ajax 4 Preview 4&lt;/a&gt;. I showed off some of the work &lt;a title="Jonathan Carter's Blog" href="http://lostintangent.com/" rel="friend met co-worker"&gt;Jonathan Carter&lt;/a&gt; and I (mostly Jonathan) did to make two-way data binding work with ASP.NET MVC. The audience really dug it.&lt;/p&gt;    &lt;p&gt;&lt;strong&gt;The Haacked and Hanselman Show        &lt;br /&gt;&lt;/strong&gt;So named because we didn’t have any agenda until about a week before the conference, this ended up being a web security talk where Scott would present a common “secure” implementation of a feature, I would then proceed to “Haack” the feature, and then Scott would fix the feature, all the while explaining what was going on. I think this was very big hit as we saw messages on Twitter like “I’m now too afraid to build a web application”. ;) Of course, I hope more attendees felt empowered rather than fearful. :P&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3484.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="IMG_3484" border="0" alt="IMG_3484" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3484_thumb.jpg" width="544" height="409" /&gt;&lt;/a&gt;The conference was held in an indoor soccer stadium since it was a venue large enough for all the attendees. They curtained off sections of the bleachers to create rooms for giving the talks. On the outside of the curtains was a large screen which allowed attendees to walk around from talk to talk with a headset on the conference floor if they didn’t feel like sitting in the bleachers.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3455.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="IMG_3455" border="0" alt="IMG_3455" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/IMG_3455_thumb.jpg" width="544" height="409" /&gt;&lt;/a&gt;Plenty of bean bags on the floor provided a comfortable place to relax and listen in. In fact, that’s where I would often find some of my new friends lounging around such as the &lt;a title="Niall Merrigan" href="http://certsandprogs.blogspot.com/"&gt;crazy Irishman&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;On the second night of the conference, we all rocked out at the big attendee party featuring the band, &lt;a title="DataRock" href="http://www.datarockmusic.com/"&gt;DataRock&lt;/a&gt; which played some rocking music with geek friendly lyrics like:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I ran into her on computer camp      &lt;br /&gt;(Was that in 84?)       &lt;br /&gt;Not sure       &lt;br /&gt;I had my commodore 64       &lt;br /&gt;Had to score &lt;/p&gt;    &lt;p&gt;&lt;em&gt;-- DataRock, Computer Camp Love&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/data-rock_2.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="data-rock" border="0" alt="data-rock" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/data-rock_thumb.jpg" width="544" height="363" /&gt;&lt;/a&gt;Many thanks to &lt;a title="NDC 2009 Highlights" href="http://www.kjetilk.com/2009/06/ndc-2009-highlights.html"&gt;Kjetil Klaussen for posting those lyrics in his NDC 09 highlights post&lt;/a&gt; because I had forgotten pretty much every lyric. :) After DataRock, we all went upstairs for the after party to enjoy a more intimate setting with LoveShack, an 80s cover band.&lt;/p&gt;  &lt;p&gt;One interesting highlight of the show was a live recording of .NET Rocks. The show was originally going to simply feature Scott Hanselman, but while hanging out in the speakers lounge Carl Franklin, one of the hosts of the show, suggested I join in the fun too.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/haack-hanselman-dotnetrocks_2.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="haack-hanselman-dotnetrocks" border="0" alt="haack-hanselman-dotnetrocks" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/haack-hanselman-dotnetrocks_thumb.jpg" width="544" height="363" /&gt;&lt;/a&gt;While it was great fun, Scott is a big, no ginormous, personality and I rarely got a word in edgewise, except for the few times I swooped right in just in time to put my foot in my mouth to apparently great comedic effect. In any case, you can &lt;a title=".NET Rocks Show #458" href="http://www.dotnetrocks.com/default.aspx?showNum=458"&gt;listen to the results&lt;/a&gt; yourself, though I hope they post the video soon to get the full effect of how much fun everyone was having. :) Be warned, there’s not a lot of real software development content in the show.&lt;/p&gt;  &lt;p&gt;The conference ended on Friday leaving all of Saturday for me to relax and actually get out and see Oslo. On Saturday, I headed out to &lt;a title="Vigeland Statue Park" href="http://en.wikipedia.org/wiki/Vigeland_Park"&gt;Vigeland Statue Park&lt;/a&gt; with an eclectic group of people, &lt;a title="Ted Neward" href="http://blogs.tedneward.com/"&gt;Ted Neward&lt;/a&gt;, &lt;a title="Rocky" href="http://www.lhotka.net/WeBlog/"&gt;Rocky Lhotka&lt;/a&gt; and his wife, &lt;a title="Jeremy Miller" href="http://codebetter.com/blogs/jeremy.miller/"&gt;Jeremy Miller&lt;/a&gt;, and Anna K{Something With Too Many Syllables in a Row}, a conference organizer herself.&lt;/p&gt;  &lt;p&gt;The park was very beautiful and I took a ton of pictures, but unfortunately I lost my camera on the flight home from Norway. :( So instead, I’ll just include this Creative Commons licensed picture taken by &lt;a title="Cebete" href="http://www.flickr.com/photos/cebete/2614928119/"&gt;Cebete from Flickr.&lt;/a&gt; The main difference was the sky was a deep blue when we visited.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/Vigeland-Park_2.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Vigeland-Park" border="0" alt="Vigeland-Park" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/NDC09TripReport_12378/Vigeland-Park_thumb.jpg" width="544" height="409" /&gt;&lt;/a&gt;That evening, Sondre Bjellås, an attendee, was kind enough to invite several of us over to his flat for a little gathering. I headed over with Bellware and Anna since everyone else was pretty much flattened by the previous weeks activities. It was great to meet non-techie Norwegians such as his wife and friends in order to get a different perspective on what it’s like to live in Norway. The answer: &lt;strong&gt;expensive!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;In an odd coincidence, on my connecting flight in Philadelphia, I ran into my good friend Walter who happened to be flying home from Belgium. In fact, we were on the same flight in the same exit row with seats right next to each other. How’s that for a funny coincidence?&lt;/p&gt;  &lt;h3&gt;Show me the Code!&lt;/h3&gt;  &lt;p&gt;Rune, one of the organizers of the conference, assures me that the videos of the talks will be posted online soon, so you’ll get to see them if you’d like. I’ve also posted my &lt;a title="Powerpoint Slides" href="http://haacked.com/code/NDC09-Demos.zip"&gt;powerpoint slides and code samples here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Please note that my talks tend to be heavy in demos so the Powerpoint decks don’t have much content in them. Likewise, the code samples represent the “before” state of my talks, not the “after” state. I usually write up a checklist for each talk which I use a to remind myself where I am in those cases where I have a total brain fart and forget my own name under the pressure of presenting.&lt;/p&gt;  &lt;h3&gt;Other NDC 09 Posts&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="Niall Merrigan" href="http://certsandprogs.blogspot.com/2009/06/ndc-09.html"&gt;Niall Merrigan’s on NDC 09&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="NDC 2009 Highlights" href="http://www.kjetilk.com/2009/06/ndc-2009-highlights.html"&gt;Kjetil Klaussen’s NDC 2009 Highlights&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="NDC 2009 Wrapup" href="http://codebetter.com/blogs/jeremy.miller/archive/2009/06/24/ndc-2009-wrapup.aspx"&gt;Jeremy Miller’s NDC 2009 Wrapup&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://haacked.com/aggbug/18626.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=fzj9UarwMhg:H9LMU_tM_hM:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=fzj9UarwMhg:H9LMU_tM_hM:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=fzj9UarwMhg:H9LMU_tM_hM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=fzj9UarwMhg:H9LMU_tM_hM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=fzj9UarwMhg:H9LMU_tM_hM:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/28/ndc2009-trip-report.aspx</guid>
            <pubDate>Mon, 29 Jun 2009 03:24:50 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18626.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/28/ndc2009-trip-report.aspx#feedback</comments>
            <slash:comments>14</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18626.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Is It Too Late To Change JSON?</title>
            <category>ASP.NET</category>
            <category>ASP.NET MVC</category>
            <link>http://haacked.com/archive/2009/06/26/too-late-to-change-json.aspx</link>
            <description>&lt;p&gt;In my last post, I wrote about the &lt;a title="JSON Hijacking" href="http://haacked.com/archive/2009/06/25/json-hijacking.aspx"&gt;hijacking of JSON arrays&lt;/a&gt;. Near the end of the post, I mentioned a comment whereby someone suggests that what really should happen is that browsers should be more strict about honoring content types and not execute code with the content type of &lt;code&gt;application/json&lt;/code&gt;.&lt;/p&gt;  &lt;p&gt;I totally agree! But then again, browsers haven’t had a good track record with being strict with such standards and it’s probably too much to expect browsers to suddenly start tightening ship, not to mention potentially breaking the web in the process.&lt;/p&gt;  &lt;p&gt;Another potential solution that came to mind was this: Can we simply change JSON? Is it too late to do that or has that boat left the harbor?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/IsItTooLateToChangeJSON_117AE/boat-left-harbor_2.jpg" rel="lightbox"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="boat-left-harbor" border="0" alt="boat-left-harbor" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/IsItTooLateToChangeJSON_117AE/boat-left-harbor_thumb.jpg" width="558" height="400" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let me run an idea by you. What if everyone got together and decided to version the JSON standard and change it in such a way that when the entire JSON response is an array, the format is no longer executable script. Note that I’m not referring to an array which is a property of a JSON object. I’m referring to the case when the entire JSON response is an array.&lt;/p&gt;  &lt;p&gt;One way to do this, and I’m just throwing this out there, is to make it such that the JSON package must always begin and end with a curly brace. JSON objects already fulfill this requirement, so their format would remain unchanged.&lt;/p&gt;  &lt;p&gt;But when the response is a JSON array, we would go from here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;code&gt;[{"Id":1,"Amt":3.14},{"Id":2,"Amt":2.72}]&lt;/code&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;to here:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;code&gt;&lt;strong&gt;{&lt;/strong&gt;[{"Id":1,"Amt":3.14},{"Id":2,"Amt":2.72}]&lt;strong&gt;}&lt;/strong&gt;&lt;/code&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Client code would simply check to see if the JSON response starts with &lt;code&gt;{[&lt;/code&gt; to determine whether it’s an array, or an object. There many alternatives, such as simply wrapping ALL JSON responses in some new characters to keep it simple.&lt;/p&gt;  &lt;p&gt;It’d be possible to do this without breaking every site out there by simply giving all the client libraries a head start. We would update the JavaScript libraries which parse JSON to recognize this new syntax, but still support the old syntax. That way, they’d work with servers which haven’t yet upgraded to the new syntax.&lt;/p&gt;  &lt;p&gt;As far as I know, most sites that make use of JSON are using it for Ajax scenarios so the site developer is in control of the client and server anyways. For sites that provide JSON as a cross-site service, upgrading the server before the clients are ready could be problematic, but not the end of the world.&lt;/p&gt;  &lt;p&gt;So what do you think? Is this worth pursuing? Not that I have any idea on how I would convince or even who I would need to convince. ;)&lt;/p&gt;  

&lt;p&gt;&lt;span class="update"&gt;UPDATE: 6/26 10:39 AM&lt;/span&gt;
&lt;a href="http://lazycoder.com" title="friend met"&gt;Scott Koon&lt;/a&gt; points out this idea is not new (I didn’t think it would be) and points to a great post that gives more detail on the &lt;a href="http://robubu.com/?p=25" title="Conflating JSON with JavaScript"&gt;specifics of executable JSON&lt;/a&gt; as it relates to the ECMAScript Specification.
&lt;/p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b2576172-bb8f-4414-b8b6-ad190bb27d3f" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com.com/tags/JavaScript/default.aspx" title="JavaScript tag" rel="tag"&gt;JavaScript&lt;/a&gt;, &lt;a href="http://haacked.com.com/tags/JSON/default.aspx" title="JSON tag" rel="tag"&gt;JSON&lt;/a&gt;, &lt;a href="http://haacked.com.com/tags/security/default.aspx" title="security tag" rel="tag"&gt;security&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18625.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=vzAP3VtJPig:O8TJSP-NVSA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=vzAP3VtJPig:O8TJSP-NVSA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=vzAP3VtJPig:O8TJSP-NVSA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=vzAP3VtJPig:O8TJSP-NVSA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=vzAP3VtJPig:O8TJSP-NVSA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/26/too-late-to-change-json.aspx</guid>
            <pubDate>Fri, 26 Jun 2009 12:00:00 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18625.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/26/too-late-to-change-json.aspx#feedback</comments>
            <slash:comments>23</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18625.aspx</wfw:commentRss>
        </item>
        <item>
            <title>JSON Hijacking</title>
            <category>ASP.NET</category>
            <category>ASP.NET MVC</category>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/06/25/json-hijacking.aspx</link>
            <description>&lt;p&gt;A while back I wrote about &lt;a title="Anatomy of a Subtle JSON Vulnerability" href="http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx"&gt;a subtle JSON vulnerability&lt;/a&gt; which could result in the disclosure of sensitive information. That particular exploit involved overriding the JavaScript &lt;code&gt;Array&lt;/code&gt; constructor to disclose the payload of a JSON array, something which most browsers do not support now.&lt;/p&gt;  &lt;p&gt;However, there’s another related exploit that seems to affect many more browsers. It was brought to my attention recently by someone at Microsoft and &lt;a title="Scott Hanselman's Blog" href="http://hanselman.com/" rel="friend met co-worker"&gt;Scott Hanselman&lt;/a&gt; and I demonstrated it at the Norwegian Developers Conference last week, though it has been &lt;a title="You don't know what my twitter leaks" href="http://hackademix.net/2009/01/13/you-dont-know-what-my-twitter-leaks/"&gt;demonstrated against Twitter in the past&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;a title="Car Theft by alicja_M on stock.xchng" href="http://www.sxc.hu/photo/676972"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="hijack" border="0" alt="hijack" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/JSONHijacking_B386/hijack_3.jpg" width="558" height="420" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Before I go further, let me give you the punch line first in terms of what this vulnerability affects. &lt;/p&gt;  &lt;p&gt;This vulnerability requires that you are exposing a JSON service which… &lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;…returns sensitive data. &lt;/li&gt;    &lt;li&gt;…returns a JSON array. &lt;/li&gt;    &lt;li&gt;…responds to GET requests. &lt;/li&gt;    &lt;li&gt;…the browser making the request has JavaScript enabled (very likely the case) &lt;/li&gt;    &lt;li&gt;…the browser making the request supports the &lt;code&gt;__defineSetter__&lt;/code&gt; method. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Thus if you never send sensitive data in JSON format, or you only send JSON in response to a POST request, etc. then your site is probably not vulnerable to &lt;em&gt;this particular vulnerability&lt;/em&gt; (though there could be others).&lt;/p&gt;  &lt;p&gt;I’m terrible with Visio, but I thought I’d give it my best shot and try to diagram the attack the best I could. In this first screenshot, we see the unwitting victim logging into the vulnerable site, and the vulnerable site issues an authentication cookie, which the browser holds onto.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Json-Hijack-1" border="0" alt="Json-Hijack-1" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/JSONHijacking_B386/Json-Hijack-1_3.png" width="550" height="148" /&gt; &lt;/p&gt;  &lt;p&gt;At some point, either in the past, or the near future, the bad guy spams the victim with an email promising a hilariously funny video of a hamster on a piano.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Json-Hijack-2" border="0" alt="Json-Hijack-2" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/JSONHijacking_B386/Json-Hijack-2_3.png" width="550" height="159" /&gt;&lt;/p&gt;  &lt;p&gt;But the link actually points to the bad guy’s website. When the victim clicks on the link, the next two steps happen in quick succession. First, the victim’s browser makes a request for the bad guy’s website.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Json-Hijack-3" border="0" alt="Json-Hijack-3" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/JSONHijacking_B386/Json-Hijack-3_6.png" width="485" height="232" /&gt; &lt;/p&gt;  &lt;p&gt;The website responds with some HTML containing some JavaScript along with a &lt;code&gt;script&lt;/code&gt; tag. When the browser sees the script tag, it makes &lt;em&gt;another GET request&lt;/em&gt; back to the vulnerable site to load the script, &lt;em&gt;sending the auth cookie along&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Json-Hijack-4" border="0" alt="Json-Hijack-4" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/JSONHijacking_B386/Json-Hijack-4_3.png" width="550" height="161" /&gt; &lt;/p&gt;  &lt;p&gt;The bad guy has tricked the victim’s &lt;em&gt;browser&lt;/em&gt; to issue a request for the JSON containing sensitive information using the browser’s credentials (aka the auth cookie). This loads the JSON array as executable JavaScript and now the bad guy has access to this data.&lt;/p&gt;  &lt;p&gt;To gain a deeper understanding, it may help to see actual code (which you can download and run) which demonstrates this attack.&lt;/p&gt;  &lt;p&gt;Note that the following demonstration is not specific to ASP.NET or ASP.NET MVC in any way, I just happen to be using &lt;a title="ASP.NET MVC Website" href="http://asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; to demonstrate it. Suppose the Vulnerable Website returns JSON with sensitive data via an action method like this.&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;[Authorize]
&lt;span class="kwrd"&gt;public&lt;/span&gt; JsonResult AdminBalances() {
  var balances = &lt;span class="kwrd"&gt;new&lt;/span&gt;[] {
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 1, Balance=3.14}, 
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 2, Balance=2.72},
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 3, Balance=1.62}
  };
  &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(balances);
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Assuming this is a method of &lt;code&gt;HomeController&lt;/code&gt;, you can access this action via a GET request for &lt;code&gt;/Home/AdminBalances&lt;/code&gt; which returns the following JSON:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p class="clear"&gt;&lt;code&gt;[{"Id":1,"Balance":3.14},{"Id":2,"Balance":2.72},{"Id":3,"Balance":1.62}]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Notice that I’m requiring authentication via the &lt;code&gt;AuthorizeAttribute&lt;/code&gt; on this action method, so an anonymous GET request will not be able to view this sensitive data.&lt;/p&gt;

&lt;p&gt;The fact that this is a JSON array is important. It turns out that a script that contains a JSON array is a valid JavaScript script and can thus be executed. A script that just contains a JSON object is not a valid JavaScript file. For example, if you had a JavaScript file that contained the following JSON:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;font style="background-color: #ffffff" size="3" face="Trebuchet MS"&gt;{"Id":1, "Balance":3.14}&lt;/font&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you had a script tag that referenced that file:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code&gt;&amp;lt;script src="http://example.com/SomeJson"&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You would get a JavaScript error in your HTML page. However, through an unfortunate coincidence, if you have a script tag that references a file only containing a JSON array, that would be considered valid JavaScript and the array gets executed.&lt;/p&gt;

&lt;p&gt;Now let’s look at the HTML page that the bad guy hosts on his/her own server:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
...
&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;="text/javascript"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
        &lt;strong&gt;Object.prototype.__defineSetter__(&lt;span class="str"&gt;'Id'&lt;/span&gt;, &lt;span class="kwrd"&gt;function&lt;/span&gt;(obj){alert(obj);});&lt;/strong&gt;
    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;="http://example.com/Home/AdminBalances"&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;body&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt; 
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;html&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;What’s happening here? Well the bad guy is changing the prototype for &lt;code&gt;Object&lt;/code&gt; using the special &lt;code&gt;__defineSetter__&lt;/code&gt; method which allows overriding what happens when a property setter is being called.&lt;/p&gt;

&lt;p class="clear"&gt;In this case, any time a property named &lt;code&gt;Id&lt;/code&gt; is being set on any object, an anonymous function is called which displays the value of the property using the alert function. Note that the script could just as easily post the data back to the bad guy, thus disclosing sensitive data.&lt;/p&gt;

&lt;p class="clear"&gt;As mentioned before, the bad guy needs to get you to visit his malicious page shortly after logging into the vulnerable site while your session on that site is still valid. Typically a phishing attack via email containing a link to the evil site does the trick.&lt;/p&gt;

&lt;p&gt;If by blind bad luck you’re still logged into the original site when you click through to the link, the browser will send your authentication cookie to the website when it loads the script referenced in the script tag. As far as the original site is concerned, you’re making a valid authenticated request for the JSON data and it responds with the data, which now gets executed in your browser. This may sound familiar as it is really a variant of a &lt;a title="Anatomy of a CSRF attack" href="http://haacked.com/archive/2009/04/02/anatomy-of-csrf-attack.aspx"&gt;Cross Site Request Forgery (CSRF) attack&lt;/a&gt; which I wrote about before.&lt;/p&gt;

&lt;p&gt;If you want to see it for yourself, you can &lt;a title="Json Hijack Demo Project" href="http://haacked.com/code/JsonHijackDemo.zip"&gt;&lt;strong&gt;download this ASP.NET MVC project&lt;/strong&gt;&lt;/a&gt; and run it locally. Make sure to login first and then go visit &lt;a href="http://haacked.com/demos/JsonAttack.html"&gt;http://haacked.com/demos/JsonAttack.html&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that this attack does not work on IE 8 which will tell you that &lt;code&gt;__defineSetter__&lt;/code&gt; is not a valid method. Last I checked, it &lt;em&gt;does&lt;/em&gt; work on Chrome and Firefox.&lt;/p&gt;

&lt;p&gt;The mitigation is simple. Either never send JSON arrays OR always require an HTTP POST to get that data (except in the case of non-sensitive data in which case you probably don’t care). For example, with ASP.NET MVC, you could use the &lt;code&gt;AcceptVerbsAttribute&lt;/code&gt; to enforce this like so:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;[Authorize]
&lt;strong&gt;[AcceptVerbs(HttpVerbs.Post)]
&lt;/strong&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; JsonResult AdminBalances() {
  var balances = &lt;span class="kwrd"&gt;new&lt;/span&gt;[] {
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 1, Balance=3.14}, 
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 2, Balance=2.72},
    &lt;span class="kwrd"&gt;new&lt;/span&gt; {Id = 3, Balance=1.62}
  };
  &lt;span class="kwrd"&gt;return&lt;/span&gt; Json(balances);
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;One issue with this approach is that many JavaScript libraries such as jQuery request JSON using a GET request by default, not POST. For example, &lt;code&gt;$.getJSON&lt;/code&gt; issues a GET request by default. So when calling into this JSON service, you need to make sure you issue a POST request with your client library.&lt;/p&gt;

&lt;p&gt;ASP.NET and WCF JSON service endpoints actually wrap their JSON in an object with the “d” property as I &lt;a title="Json Vulnerability" href="http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx"&gt;wrote about a while back&lt;/a&gt;. While it might seem odd to have to go through this property to get access to your data, this awkwardness is eased by the fact that the generated client proxies for these services strip the “d” property so the end-user doesn’t need to know it was ever there.&lt;/p&gt;

&lt;p&gt;With ASP.NET MVC (and other similar frameworks), a significant number of developers are not using client generated proxies (we don’t have them) but instead using jQuery and other such libraries to call into these methods, making the “d” fix kind of awkward.&lt;/p&gt;

&lt;h3&gt;What About Checking The Header?&lt;/h3&gt;

&lt;p&gt;Some of you might be wondering, “why not have the JSON service check for a special header such as the &lt;code&gt;X-Requested-With: XMLHttpRequest&lt;/code&gt; or &lt;code&gt;Content-Type: application/json&lt;/code&gt; before serving it up in response to a GET request?” I too thought this might be a great mitigation because most client libraries send one or the other of these headers, but a browser’s GET request in response to a script tag would not. &lt;/p&gt;

&lt;p&gt;The problem with this (as a couple of co-workers pointed out to me) is that at some point in the past, the user may have made a legitimate GET request for that JSON in which case it may well be cached in the user’s browser or in some proxy server in between the victim’s browser and the vulnerable website. In that case, when the browser makes the GET request for the script, the request might get fulfilled from the browser cache or proxy cache. You could try setting &lt;code&gt;No-Cache&lt;/code&gt; headers, but at that point you’re trusting that the browser and all proxy servers correctly implement caching and that the user can’t override that accidentally.&lt;/p&gt;

&lt;p&gt;Of course, this particular caching issue isn’t a problem if you’re serving up your JSON using SSL.&lt;/p&gt;

&lt;h3&gt;The real issue?&lt;/h3&gt;

&lt;p&gt;There’s a post at the Mozilla Developer Center which states that object and array initializers &lt;a title="initializers should not invoke setters" href="https://developer.mozilla.org/web-tech/2009/04/29/object-and-array-initializers-should-not-invoke-setters-when-evaluated/"&gt;should not invoke setters when evaluated&lt;/a&gt;, which at this point, I tend to agree with, though a comment to that post argues that perhaps browsers really shouldn’t execute scripts regardless of their content type, which is also a valid complaint.&lt;/p&gt;

&lt;p&gt;But at the end of the day, assigning blame doesn’t make your site more secure. These type of browser quirks will continue to crop up from time to time and we as web developers need to deal with them. Chrome 2.0.172.31 and Firefox 3.0.11 were both vulnerable to this. IE 8 was not because it doesn’t support this method. I didn’t try it in IE 7 or IE 6.&lt;/p&gt;

&lt;p&gt;It seems to me that to be secure by default, the default behavior for accessing JSON should probably be POST and you should opt-in to GET, rather than the other way around as is done with the current client libraries. What do you think? And how do other platforms you’ve worked with handle this? I’d love to hear your thoughts.&lt;/p&gt;

&lt;p&gt;In case you missed it, here are the repro steps again: &lt;a title="Json Hijack Demo Project" href="http://haacked.com/code/JsonHijackDemo.zip"&gt;&lt;strong&gt;Download this ASP.NET MVC project&lt;/strong&gt;&lt;/a&gt; and run it locally. Make sure to login first and then go visit &lt;a href="http://haacked.com/demos/JsonAttack.html"&gt;http://haacked.com/demos/JsonAttack.html&lt;/a&gt; in the same browser.&lt;/p&gt;

&lt;p class="update"&gt;I followed up this post with &lt;a href="http://haacked.com/archive/2009/06/26/too-late-to-change-json.aspx" title="Too late to change JSON?"&gt;a proposal to fix JSON&lt;/a&gt; to prevent this particular issue.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:d58ae706-c954-42ea-ac1c-f4d2d17a730c" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/json/default.aspx" rel="tag"&gt;json&lt;/a&gt;, &lt;a href="http://haacked.com/tags/javascript/default.aspx" rel="tag"&gt;javascript&lt;/a&gt;, &lt;a href="http://haacked.com/tags/security/default.aspx" rel="tag"&gt;security&lt;/a&gt;, &lt;a href="http://haacked.com/tags/browsers/default.aspx" rel="tag"&gt;browsers&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18624.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=1MeC-s1bo7s:op5mJ0wYv9w:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=1MeC-s1bo7s:op5mJ0wYv9w:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=1MeC-s1bo7s:op5mJ0wYv9w:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=1MeC-s1bo7s:op5mJ0wYv9w:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=1MeC-s1bo7s:op5mJ0wYv9w:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/25/json-hijacking.aspx</guid>
            <pubDate>Thu, 25 Jun 2009 19:16:24 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18624.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/25/json-hijacking.aspx#feedback</comments>
            <slash:comments>29</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18624.aspx</wfw:commentRss>
        </item>
        <item>
            <title>And Get Rid Of Those Pesky Programmers</title>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/06/12/getting-rid-of-programmers.aspx</link>
            <description>&lt;p&gt;Every now and then some email or website comes along promising to prove Fred Brooks wrong about this crazy idea he wrote in &lt;a title="The Mythical Man Month" href="http://www.amazon.com/gp/product/0201835959?ie=UTF8&amp;amp;tag=youvebeenhaac-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0201835959"&gt;The Mythical Man Month&lt;/a&gt; (highly recommended reading!) that &lt;a title="There is no silver bullet" href="http://www.virtualschool.edu/mon/SoftwareEngineering/BrooksNoSilverBullet.html"&gt;there is no silver bullet&lt;/a&gt; which by itself will provide a tenfold improvement in productivity, reliability, and simplicity within a decade.&lt;/p&gt;  &lt;p&gt;This time around, the promise was much like others, but they felt the need to note that their revolutionary new application/framework/doohickey will allow business analysts to directly build applications 10 times as fast &lt;strong&gt;without the need for programmers!&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/AndGetRidOfThosePeskyProgrammers_A0BE/revenge-nerds_2.jpg" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="revenge-nerds" border="0" alt="revenge-nerds" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/AndGetRidOfThosePeskyProgrammers_A0BE/revenge-nerds_thumb.jpg" width="404" height="285" /&gt;&lt;/a&gt; &lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Ah yeah! Get rid of those foul smelling pesky programmers! We don’t need em!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now wait one dag-burn minute! Seriously?!&lt;/p&gt;  &lt;p&gt;I’m going to try real hard for a moment to forget they said that and not indulge my natural knee jerk reaction which is to flip the bozo bit immediately. If I were a more reflective person, this would raised a disturbing question:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Why are these business types so eager to get rid of us programmers?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It’s easy to blame the suits for not understanding software development and forcing us into a &lt;a title="People Skills on Hulu" href="http://www.hulu.com/watch/12879/office-space-people-skills"&gt;Tom Smykowski moment&lt;/a&gt; having to defend what it is we do around here.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Well-well look. I already told you: I deal with the god damn customers so the engineers don't have to. I have people skills; I am good at dealing with people. Can't you understand that? What the hell is wrong with you people?&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Maybe, as Steven “Doc” List quotes from Cool Hand Luke in his latest &lt;a title="Think Before You Speak" href="http://msdn.microsoft.com/en-us/magazine/dd882508.aspx"&gt;End Bracket article&lt;/a&gt; on effective communication for MSDN Magazine,&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;What we've got here is a failure to communicate.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a title="Leon Bambrick" href="http://www.secretgeek.net/"&gt;Leon Bambrick&lt;/a&gt; (aka SecretGeek) recently wrote about this phenomena in his post entitled, &lt;a title="Programmer communication" href="http://www.secretgeek.net/program_communicate_4reasons.asp"&gt;The Better You Program, The Worse You Communicate&lt;/a&gt;, in which he outlines how techniques that make us effective software developers do not apply to communicating with other humans.&lt;/p&gt;  &lt;p&gt;After all, we can sometimes be hard to work with. We’re often so focused on the technical aspects and limitations of a solution that we unknowingly confuse the stakeholders with jargon and annoy them by calling their requirements “ludicrous”. Sometimes, we fail to deeply understand their business and resort to &lt;a title="Vendor Client Relationships" href="http://www.youtube.com/watch?v=R2a8TRSgzZY"&gt;making fun of our stakeholders&lt;/a&gt; rather than truly understanding their needs. No wonder they want to do the programming themselves!&lt;/p&gt;  &lt;p&gt;Ok, ok. It’s not always like this. Not every programmer is like this and it isn’t fair to lay all the blame at our feet. I’m merely trying to empathize and understand the viewpoint that would lead to this idea that moving programmers out of the picture would be a &lt;em&gt;good thing&lt;/em&gt;.&lt;/p&gt;  &lt;p&gt;Some blame does deserve to lie squarely at the feet of these snake oil salespeople, because at the moment, they’re selling a lie. What they’d like customers to believe is your average business analyst simply describes the business in their own words to the software, and it spits out an application.&lt;/p&gt;  &lt;p&gt;The other day, I started an internal email thread describing in hand-wavy terms some &lt;a title="Alternative To Expressions" href="http://haacked.com/archive/2009/06/02/alternative-to-expressions.aspx"&gt;feature I thought might be interesting&lt;/a&gt;. A couple hours later, my co-worker had an implementation ready to show off. &lt;/p&gt;  &lt;p&gt;Now &lt;em&gt;that&lt;/em&gt; my friends, is the best type of declarative programming. I merely declared my intentions, waited a bit, and voila!  Code! Perhaps that’s along the lines of what these types of applications hope to accomplish, but there’s one problem. In the scenario I described, it required feeding requirements to a human. If I had sent that email to some software, it would have no idea what to do with it.&lt;/p&gt;  &lt;p&gt;At some point, something close to this might be possible, but only when software has reached the point where it can exhibit sophisticated artificial intelligence and really deal with fuzziness. In other words, when the software itself becomes the programmer, only then might you really get rid of the human programmer. But I’m sorry to say, you’re still working with a programmer, just one who doesn’t scoff at your requirements arrogantly (at least not in your face while it plots to take over the world, Copper-top).&lt;/p&gt;  &lt;p&gt;Until that day, when a business analyst wires together an applications with Lego-like precision using such frameworks, that analyst has in essence become a programmer. That work requires many of the same skills that developers require. At this point, you really haven’t gotten rid of programmers, you’ve just converted a business type into a programmer, but one who happens to know the business very well.&lt;/p&gt;  &lt;p&gt;In the end, no matter how “declarative” a system you build and how foolproof it is such that a non-programmer can build applications by dragging some doohickeys around a screen, there’s very little room for imprecision and fuzziness, something humans handle well, but computers do not, as Spock demonstrated so well in an episode of Star Trek.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“Computer, compute the last digit of PI” - Spock&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Throw into the mix that the bulk of the real work of building an application is not the coding, but all the work surrounding that, as Udi Dahan points out in his post on &lt;a title="The Fallacy of ReUse" href="http://www.udidahan.com/2009/06/07/the-fallacy-of-reuse/"&gt;The Fallacy of ReUse&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;This is not to say that I don’t think we should continue to invest in building better and better tools. After all, the history of software development is about building better and better higher level tools to make developers more productive. I think the danger lies in trying to remove the discipline and traits that will always be required when using these tools to build applications.&lt;/p&gt;  &lt;p&gt;Even when you can tell the computer what you want in human terms, and it figures it out, it’s important to still follow good software development principles, ensure quality checks, tests, etc…&lt;/p&gt;  &lt;p&gt;The lesson for us programmers, I believe is two-fold. One, we have to educate our stakeholders about how software production really works. Even if they won’t listen, a little knowledge and understanding here goes a long way. Be patient, don’t be condescending, and hope for the best. Secondly, we have to educate ourselves about the business in a deep manner so that we are seen as valuable business partners who happen to write the code that matters.&lt;/p&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b8ae38f8-ac49-44b3-9b3e-482f19bacb83" class="wlWriterEditableSmartContent"&gt;Technorati Tags: &lt;a href="http://technorati.com/tags/software+development" rel="tag"&gt;software development&lt;/a&gt;,&lt;a href="http://technorati.com/tags/business+analysts" rel="tag"&gt;business analysts&lt;/a&gt;,&lt;a href="http://technorati.com/tags/silver+bullet" rel="tag"&gt;silver bullet&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18623.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=7XXiBW-AeW4:4SNG6zx0JnA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=7XXiBW-AeW4:4SNG6zx0JnA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=7XXiBW-AeW4:4SNG6zx0JnA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=7XXiBW-AeW4:4SNG6zx0JnA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=7XXiBW-AeW4:4SNG6zx0JnA:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/12/getting-rid-of-programmers.aspx</guid>
            <pubDate>Sat, 13 Jun 2009 03:49:54 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18623.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/12/getting-rid-of-programmers.aspx#feedback</comments>
            <slash:comments>47</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18623.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ASP.NET MVC Installer For Visual Studio 2010 Beta 1 And Roadmap</title>
            <category>ASP.NET</category>
            <category>ASP.NET MVC</category>
            <link>http://haacked.com/archive/2009/06/09/aspnetmvc-vs10beta1-roadmap.aspx</link>
            <description>&lt;p&gt;A little while ago I announced our plans for &lt;a title="ASP.NET MVC Website" href="http://asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; as it relates to Visual Studio 2010. ASP.NET MVC wasn’t included as part of Beta 1, which raised a few concerns by some (if not conspiracy theories!) ;). The reason for this was simple as I pointed out:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;One thing you’ll notice is that ASP.NET MVC is not included in Beta 1. The reason for this is that Beta 1 started locking down before MVC 1.0 shipped. ASP.NET MVC will be included as part of the package in VS10 Beta 2.&lt;/p&gt;    &lt;p&gt;…&lt;/p&gt;    &lt;p&gt;We’re working hard to have an out-of-band installer which will install the project templates and tooling for ASP.NET MVC which works with VS2010 Beta 1 sometime in June on CodePlex. Sorry for the inconvenience. I’ll blog about it once it is ready.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Today I’m happy to announce that we’re done with the work I described and the installer is &lt;a title="ASP.NET MVC For Visual Studio 2010 Beta 1" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527"&gt;&lt;strong&gt;now available on CodePlex&lt;/strong&gt;&lt;/a&gt;. Be sure to give it a try as many of the new VS10 features intended to support the TDD workflow fit very nicely with ASP.NET MVC, which &lt;a title="Scott Guthrie's Blog" href="http://weblogs.asp.net/scottgu" rel="friend met co-worker"&gt;ScottGu&lt;/a&gt; will describe in an upcoming blog post.&lt;/p&gt;  &lt;p&gt;If you run into problems with the intaller, try out this &lt;a title="Troubleshooting the MVC for VS10 Beta 1 installer" href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx"&gt;troubleshooting guide by Jacques&lt;/a&gt;, the developer who did the installer work and do provide feedback.&lt;/p&gt;  &lt;p&gt;You’ll notice that the installer says this is ASP.NET MVC &lt;em&gt;1.1&lt;/em&gt;, but as the readme notes point out, this is really ASP.NET MVC &lt;em&gt;1.0&lt;/em&gt; retargeted for Visual Studio 2010. The 1.1 is just a placeholder version number. We bumped up the version number to avoid runtime conflicts with ASP.NET MVC 1.0. All of this and more is described in the &lt;a title="Release Notes" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527#DownloadId=71127"&gt;&lt;strong&gt;Release Notes&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;When VS10 Beta 2 comes out, you won’t need to download a separate standalone installer to get ASP.NET MVC (though a standalone installer will be made available for VS2008 users that will run on ASP.NET 3.5 SP1). A pre-release version of ASP.NET MVC 2 will be included as part of the Beta 2 installer as described in the … &lt;/p&gt;  &lt;h2&gt;Roadmap&lt;/h2&gt;  &lt;p&gt;&lt;a title="Photo credit: arinas74 on stock.xchng" href="http://www.sxc.hu/photo/1158482"&gt;&lt;img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="Road Blur. Photo credit: arinas74 on stock.xchng" border="0" alt="Road Blur: Photo credit: arinas74 on stock.xchng" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/ASP.NETMVCInstallerForVisualStudio2010Be_7EAC/fast-road_3.jpg" width="524" height="349" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I recently published the &lt;a title="ASP.NET MVC Roadmap" href="http://aspnet.codeplex.com/Wiki/View.aspx?title=Road%20Map&amp;amp;referringTitle=Home"&gt;&lt;strong&gt;Roadmap for ASP.NET MVC 2&lt;/strong&gt;&lt;/a&gt; which gives a high level look at what features we plan to do for ASP.NET MVC 2. The features are noticeably lacking in details as we’re deep in the planning phase trying to gather pain points.&lt;/p&gt;  &lt;p&gt;Right now, we’re avoiding focusing the implementation details as much as possible. When designing software, it’s very easy to have preconceived notions about what the solution should be, even when we really don’t have a full grasp of the problem that needs to be solved.&lt;/p&gt;  &lt;p&gt;Rather than guiding people towards what we think the solution is, I hope to focus on making sure we understand the problem domain and what people want to accomplish with the framework. That leaves us free to try out alternative approaches that we might not have considered before such as &lt;a title="Alternative Approach to strongly typed helpers" href="http://haacked.com/archive/2009/06/02/alternative-to-expressions.aspx"&gt;alternatives to expression based URL helpers&lt;/a&gt;. Maybe the alternative will work out, maybe not. Ideally, I’d like to have several design alternatives to choose from for each feature.&lt;/p&gt;  &lt;p&gt;As we get further along the process, I’ll be sure to flesh out more and more details in the Roadmap and share them with you.&lt;/p&gt;  &lt;h2&gt;Snippets&lt;/h2&gt;  &lt;p&gt;One cool new feature of VS10 is that snippets now work in the HTML editor. Jeff King from the &lt;a title="Visual Web Developer Team Blog" href="http://blogs.msdn.com/webdevtools/"&gt;Visual Web Developer team&lt;/a&gt; sent me the snippets we plan to include in the next version. They are also downloadable from the &lt;a title="Release page" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527"&gt;CodePlex release page&lt;/a&gt;. Installation is very simple:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Installation Steps: &lt;/p&gt;    &lt;p&gt;1) Unzip "ASP.NET MVC Snippets.zip" into "C:\Users\&amp;lt;username&amp;gt;\Documents\Visual Studio 10\Code Snippets\Visual Web Developer\My HTML Snippets", where "C:\" is your OS drive.      &lt;br /&gt;2) Visual Studio will automatically detect these new files.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Try them out and let us know if you have ideas for snippets that will help you be more productive.&lt;/p&gt;  &lt;p&gt;Important Links:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a title="ASP.NET MVC For Visual Studio 2010 Beta 1" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527"&gt;CodePlex Download Page&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a title="ASP.NET MVC For Visual Studio 2010 Beta 1 Release Notes" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28527#DownloadId=71127"&gt;Release Notes&lt;/a&gt; (also linked to from above page) &lt;/li&gt;    &lt;li&gt;&lt;a title="ASP.NET MVC 2 Roadmap" href="http://aspnet.codeplex.com/Wiki/View.aspx?title=Road%20Map&amp;amp;referringTitle=Home"&gt;ASP.NET MVC 2 Roadmap&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a title="Troubleshooting the MVC for VS10 Beta 1 installer" href="http://weblogs.asp.net/jacqueseloff/archive/2009/06/09/troubleshooting-the-mvc-installer-for-visual-studio-2010-beta-1.aspx"&gt;Troubleshooting Info for this installer&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e0706372-b5d7-480e-9382-7ea3cd3481c6" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/asp.net/default.aspx" rel="tag"&gt;asp.net&lt;/a&gt;, &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/visual+studio+2010/default.aspx" rel="tag"&gt;visual studio 2010&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18622.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=_WpY3mNh0g0:Q9ewfQ0pbyk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=_WpY3mNh0g0:Q9ewfQ0pbyk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=_WpY3mNh0g0:Q9ewfQ0pbyk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=_WpY3mNh0g0:Q9ewfQ0pbyk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=_WpY3mNh0g0:Q9ewfQ0pbyk:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/09/aspnetmvc-vs10beta1-roadmap.aspx</guid>
            <pubDate>Tue, 09 Jun 2009 17:59:37 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18622.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/09/aspnetmvc-vs10beta1-roadmap.aspx#feedback</comments>
            <slash:comments>35</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18622.aspx</wfw:commentRss>
        </item>
        <item>
            <title>An Alternative Approach To Strongly Typed Helpers</title>
            <category>ASP.NET MVC</category>
            <category>ASP.NET</category>
            <link>http://haacked.com/archive/2009/06/02/alternative-to-expressions.aspx</link>
            <description>&lt;p&gt;One of the features contained in the &lt;a title="ASP.NET MVC 1.0 Source" href="http://aspnet.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=24471"&gt;MVC Futures&lt;/a&gt; project is the ability to generate action links in a strongly typed fashion using expressions. For example:&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.ActionLink&amp;lt;HomeController&amp;gt;(c =&amp;gt; c.Index()) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Will generate a link to to the &lt;code&gt;Index&lt;/code&gt; action of the &lt;code&gt;HomeController&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s a pretty slick approach, but it is not without its drawbacks. First, the syntax is not one you’d want to take as your prom date. I guess you can get used to it, but a lot of people who see it for the first time kind of recoil at it.&lt;/p&gt;

&lt;p&gt;The other problem with this approach is performance as seen in this &lt;a title="ASP.NET MVC Performance" href="http://www.slideshare.net/rudib/aspnet-mvc-performance"&gt;slide deck&lt;/a&gt; I learned about from &lt;a title="Brad Wilson" href="http://bradwilson.typepad.com/" rel="friend met co-worker"&gt;Brad Wilson&lt;/a&gt;. One of the pain points the authors of the deck found was that the compilation of the expressions was very slow.&lt;/p&gt;

&lt;p&gt;I had thought that we might be able to mitigate these performance issues via some sort of caching of the compiled expressions, but that might not work very well. Consider the following case:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt; &lt;span class="kwrd"&gt;for&lt;/span&gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 20; i++) { &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;

  &lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= Html.ActionLink&amp;lt;HomeController&amp;gt;(c =&amp;gt; c.Foo(i)) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;

&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt; } &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Each time through that loop, the expression is the same: &lt;code&gt;c =&amp;gt; c.Foo(i)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But the value of the captured “i” is different each time. If we try to cache the compiled expression, what happens?&lt;/p&gt;

&lt;p&gt;So I started thinking about an alternative approach using code generation against the controllers and circulated an email internally. One approach was to code gen action specific action link methods. Thus the about link for the home controller (assuming we add an id parameter for demonstration purposes) would be:&lt;/p&gt;

&lt;div class="dropshadow code"&gt;
  &lt;div class="innerbox"&gt;
    &lt;pre class="csharpcode"&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;= HomeAboutLink(123) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;Brad had mentioned many times that while he likes expressions, he’s no fan of using them for links and he tends to write specific action link methods just like the above. So what if we could generate them for you so you didn’t have to write them by hand?&lt;/p&gt;

&lt;p&gt;A couple hours after starting the email thread, &lt;a title="David Ebbo's Blog" href="http://blogs.msdn.com/davidebb/" rel="friend met co-worker"&gt;David Ebbo&lt;/a&gt; had an &lt;a title="A build provider to simplify action links" href="http://blogs.msdn.com/davidebb/archive/2009/06/01/a-buildprovider-to-simplify-your-asp-net-mvc-action-links.aspx#comments"&gt;implementation of this ready to show off&lt;/a&gt;. He probably had it done earlier for all I know, I was stuck in meetings. Talk about the best kind of declarative programming. I declared what I wanted roughly with hand waving, and a little while later, the code just appears! ;)&lt;/p&gt;

&lt;p&gt;David’s approach uses a BuildProvider to reflect over the Controllers and Actions in the solution and generate custom action link methods for each one. There’s plenty of room for improvement, such as ensuring that it honors the &lt;code&gt;ActionNameAttribute&lt;/code&gt; and generating overloads, but it’s a neat proof of concept.&lt;/p&gt;

&lt;p&gt;One disadvantage of this approach compared to the expression based helpers is that there’s no refactoring support. However, if you rename an action method, you will get a compilation error rather than a runtime error, which is better than what you get without either. One advantage of this approach is that it performs fast and doesn’t rely on the funky expression syntax.&lt;/p&gt;

&lt;p&gt;These are some interesting tradeoffs we’ll be looking closely at for the next version of &lt;a title="ASP.NET MVC Website" href="http://asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt;.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:a093962b-2c9f-4fba-881c-564ae590b5b2" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com/tags/aspnetmvc/default.aspx" rel="tag"&gt;aspnetmvc&lt;/a&gt;, &lt;a href="http://haacked.com/tags/asp.net/default.aspx" rel="tag"&gt;asp.net&lt;/a&gt;, &lt;a href="http://haacked.com/tags/helpers/default.aspx" rel="tag"&gt;helpers&lt;/a&gt;, &lt;a href="http://haacked.com/tags/actionlink/default.aspx" rel="tag"&gt;actionlink&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18621.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=PaMP1fmEb1s:j6jdAZFMO4c:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=PaMP1fmEb1s:j6jdAZFMO4c:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=PaMP1fmEb1s:j6jdAZFMO4c:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=PaMP1fmEb1s:j6jdAZFMO4c:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=PaMP1fmEb1s:j6jdAZFMO4c:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/06/02/alternative-to-expressions.aspx</guid>
            <pubDate>Tue, 02 Jun 2009 15:56:16 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18621.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/06/02/alternative-to-expressions.aspx#feedback</comments>
            <slash:comments>34</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18621.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Writing A Page To A String</title>
            <category>ASP.NET</category>
            <category>Software Development</category>
            <link>http://haacked.com/archive/2009/05/29/writing-page-to-string.aspx</link>
            <description>&lt;p&gt;ASP.NET Pages are designed to stream their output directly to a response stream. This can be a huge performance benefit for large pages as it doesn’t require buffering and allocating very large strings before rendering. Allocating large strings can put them on the &lt;a title="Large Object Heap" href="http://msdn.microsoft.com/en-us/magazine/cc534993.aspx"&gt;Large Object Heap&lt;/a&gt; which means they’ll be sticking around for a while.&lt;/p&gt;  &lt;p&gt;&lt;a title="Photo by crisderaud on stock.xchng" href="http://www.sxc.hu/photo/979650"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="string" border="0" alt="string" align="left" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/RenderingaPageToAStringWithoutUsingAResp_7EC8/string_3.jpg" width="210" height="240" /&gt;&lt;/a&gt; However, there are many cases in which you really want to render a page to a string so you can perform some post processing. I wrote about one means &lt;a title="Using Response Filter" href="http://haacked.com/archive/2007/07/29/cleanup-the-crap-that-windows-live-writer-injects-with-this.aspx"&gt;using a Response filter eons ago&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;However, recently, I learned about a method of the Page class I never noticed which allows me to use a much lighter weight approach to this problem.&lt;/p&gt;  &lt;p&gt;The method in question is &lt;code&gt;CreateHtmlTextWriter&lt;/code&gt; which is protected, but also virtual.&lt;/p&gt;  &lt;p&gt;So here’s an example of the code-behind for a page that can leverage this method to filter the output before its sent to the browser.&lt;/p&gt;  &lt;div class="dropshadow code"&gt;   &lt;div class="innerbox"&gt;     &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;partial&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FilterDemo : System.Web.UI.Page
{
  HtmlTextWriter _oldWriter = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
  StringWriter _stringWriter = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringWriter();

  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; HtmlTextWriter CreateHtmlTextWriter(TextWriter tw)
  {
    _oldWriter = &lt;span class="kwrd"&gt;base&lt;/span&gt;.CreateHtmlTextWriter(tw);
    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.CreateHtmlTextWriter(_stringWriter);
  }

  &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Render(HtmlTextWriter writer)
  {
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Render(writer);
    &lt;span class="kwrd"&gt;string&lt;/span&gt; html = _stringWriter.ToString();
    html = html.Replace(&lt;span class="str"&gt;"REPLACE ME!"&lt;/span&gt;, &lt;span class="str"&gt;"IT WAS REPLACED!"&lt;/span&gt;);
    _oldWriter.Write(html);
  }
}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;p class="clear"&gt;In the &lt;code&gt;CreateHtmlTextWriter&lt;/code&gt; method, we simply use the original logic to create the &lt;code&gt;HtmlTextWriter&lt;/code&gt; and store it away in an instance variable.&lt;/p&gt;

&lt;p&gt;Then we use the same logic to create a new &lt;code&gt;HtmlTextWriter&lt;/code&gt;, but this one has our own &lt;code&gt;StringWriter&lt;/code&gt; as the underlying &lt;code&gt;TextWriter&lt;/code&gt;. The &lt;code&gt;HtmlTextWriter&lt;/code&gt; passed into the &lt;code&gt;Render&lt;/code&gt; method is the one we created. We call &lt;code&gt;Render&lt;/code&gt; on that and grab the output from the &lt;code&gt;StringWriter&lt;/code&gt; and now can do all the replacements we want. We finally write the final output to the original &lt;code&gt;HtmlTextWriter&lt;/code&gt; which is hooked up to the response.&lt;/p&gt;

&lt;p&gt;A lot of caveats apply in using this technique. First, as I mentioned before, for large pages, you could be killing scalability and performance by doing this. Also, I haven’t tested this with output caching, async pages, etc… etc…, so your mileage may vary.&lt;/p&gt;

&lt;p&gt;Note, if you want to call one page from another, and get the output as a string within the first page, you can pass your own &lt;code&gt;TextWriter&lt;/code&gt; to &lt;code&gt;Server.Execute&lt;/code&gt;, so this technique is not necessary in that case.&lt;/p&gt;

&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:e6e3e5aa-0c75-4bf9-9e05-ffeadda27a97" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com.com/tags/asp.net/default.aspx" title="asp.net tag" rel="tag"&gt;asp.net&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18620.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Wkj8st7pXVA:WsueV1BZEwU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=Wkj8st7pXVA:WsueV1BZEwU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Wkj8st7pXVA:WsueV1BZEwU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=Wkj8st7pXVA:WsueV1BZEwU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=Wkj8st7pXVA:WsueV1BZEwU:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/05/29/writing-page-to-string.aspx</guid>
            <pubDate>Fri, 29 May 2009 16:43:28 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18620.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/05/29/writing-page-to-string.aspx#feedback</comments>
            <slash:comments>12</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18620.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Fright on Mt Si</title>
            <category>Personal</category>
            <link>http://haacked.com/archive/2009/05/24/panic-mt-si.aspx</link>
            <description>&lt;p&gt;Being that it’s a glorious Memorial Day Weekend up here in the Northwest, my &lt;a title="Eilon" href="http://weblogs.asp.net/leftslipper/" rel="friend met co-worker"&gt;co-worker Eilon&lt;/a&gt; (developer lead for ASP.NET MVC) and I decided to go on a hike to Mt Si where we had a bit of a scary moment.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1129A/in-front-of-mt-si_2.jpg" rel="lightbox"&gt;&lt;img style="display: block;" title="in-front-of-mt-si" border="0" alt="in-front-of-mt-si" align="left" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1129A/in-front-of-mt-si_thumb.jpg" width="244" height="184" /&gt;&lt;/a&gt; I first learned about Mt Si at the company picnic last year, seen behind me and Cody in this photo. I remember seeing the imposing cliff face and thinking to myself, &lt;em&gt;I want to climb up there&lt;/em&gt;. I imagined the view would be quite impressive.&lt;/p&gt;  &lt;p&gt;Mt Si is a moderately strenuous hike 8 miles round trip with an elevation gain of 3100 feet taking you to about 3600 feet, according to the &lt;a title="WTA website" href="http://www.wta.org/go-hiking/hikes/mount-si"&gt;Washington Trails Association website&lt;/a&gt;. Given that it is a very popular hike and that this was a three-day weekend, we figured we’d get an early start by heading over there at 7 AM.&lt;/p&gt;  &lt;p&gt;That ended up being a good idea as the parking lot had quite a few cars already, but it wasn’t full by any means. This is a picture of the trail head which starts the hike off under a nice canopy of green.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20007.jpg" rel="lightbox[mt-si]" title="Trail Head"&gt;&lt;img style="display: block;" title="Trail Head" border="0" alt="Trail Head" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20007_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;Right away, the no-nonsense trail starts you off huffing uphill amongst a multitude of trees.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20010.jpg" rel="lightbox[mt-si]" title="Uphill Climb"&gt;&lt;img style="display: block;" title="Uphill Climb" border="0" alt="Uphill Climb" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20010_thumb.jpg" width="421" height="560" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Along the way, there are the occasional diversions. For example, this one won me $10 as the result of a bet that I wouldn’t walk to the edge of the tree overhanging the drop off.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20016.jpg" rel="lightbox[mt-si]" title="Winning a bet"&gt;&lt;img style="display: block;" title="Winning a bet" border="0" alt="Winning a bet" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20016_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;When you get to the top, there’s a great lookout with amazing views. But what caught our attention is a rock outcropping called the “Haystack”, which takes you up another 500 feet. Near the base of the Haystack is a small memorial for &lt;a title="Man plummets to death on Mt Si" href="http://www.kirotv.com/news/17326582/detail.html"&gt;those who’ve died&lt;/a&gt; from plummeting off its rocky face. It’s not a trivial undertaking, but I demanded we try.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20026.jpg" rel="lightbox[mt-si]" title="The Haystack"&gt;&lt;img style="display: block;" title="The Haystack" border="0" alt="The Haystack" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20026_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;Unfortunately, there’s nothing in the above picture to provide a better sense of scale for this scramble. In the following picture you can see some people pretty much scooting down the steep slope on their butts.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20028.jpg" rel="lightbox[mt-si]" title="Scrambling down the haystack"&gt;&lt;img style="display: block;" title="Scrambling down the haystack" border="0" alt="Scrambling down the haystack" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20028_thumb.jpg" width="421" height="560" /&gt;&lt;/a&gt;Once they were down, we set up and reached around two thirds of the way when I made the mistake of looking back and made a remark about how it’s going to be much more difficult going down. That started getting us nervous because it’s always easier going up than down.&lt;/p&gt;  &lt;p&gt;It would have probably been best if I hadn’t made that remark because the climb wasn’t really that difficult, but introducing a bit of nervousness into the mix can really sabotage one’s confidence, which you definitely want on a climb.&lt;/p&gt;  &lt;p&gt;At that point, the damage was done and we decided we had enough and started heading back down. Better to try again another day when we felt more confident. At that moment, a couple heading down told us we were almost there and it wasn’t so bad. Our success heading back down and their comments started to bolster our confidence to the point where I was ready to head back up, until I noticed that my shoe felt odd.&lt;/p&gt;  &lt;p&gt;What I hadn’t noticed while climbing on the steep face was that my sole had almost completely detached from my hiking boot during the climb. Fortunately, Eilon had some duct tape on hand allowing me to make this ghetto looking patch job.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/IMGP3194_1.jpg" rel="lightbox[mt-si]" title="MacGuyver Repair Job"&gt;&lt;img style="display: block;" title="MacGuyver Repair Job" border="0" alt="MacGuyver Repair Job" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/IMGP3194_thumb_1.jpg" width="558" height="420" /&gt;&lt;/a&gt;At this point I had a mild panic because I worried that the duct tape would cause me to lose grip with my boots on the way down. And frankly, I was pissed off as well, as I’ve had these boots for a few years, but haven’t hiked in them all that often. What a perfect time for them completely fall apart!&lt;/p&gt;  &lt;p&gt;Fortunately, I didn’t have much problem climbing back down and we stopped at the first summit to take some pictures and have a brief snack.&lt;/p&gt;  &lt;p&gt;Not having the guts today to climb the big rock, I scrambled up a much smaller one and got this great view of Mt Rainier in its full splendor.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20037.jpg" rel="lightbox[mt-si]" title="Mt Rainier"&gt;&lt;img style="display: block;" title="Mt Rainier" border="0" alt="Mt Rainier" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20037_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;The view from the top is quite scenic and using binoculars, I was able to check on my family back in Bellevue (&lt;em&gt;joke&lt;/em&gt;).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20045.jpg" rel="lightbox[mt-si]" title="Checking on the house"&gt;&lt;img style="display: block;" title="Checking on the house" border="0" alt="Checking on the house" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20045_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;Going back down was much quicker than the way up and we had a blast of it practically trail running the first part, until my other shoe gave out.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20050.jpg" rel="lightbox[mt-si]" title="Boots at the end"&gt;&lt;img style="display: block;" title="Boots at the end" border="0" alt="Boots at the end" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20050_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;Guess the warranty must have run out yesterday. ;) Fortunately, Eilon, who was prepared with the Duct tape, also had all terrain sandals with him, which I wore the rest of the way. Next time, I think I’ll ditch the Salomon boots and try Merrells which other hikers I ran into were wearing.&lt;/p&gt;  &lt;p&gt;Despite the mishaps, the hike was really a fun romp in the woods and I highly recommend it to anyone in the Seattle area to give it a try. Go early to avoid the crowds. I doubled my $10 in an over/under bet where I took 140 and over cars in the lot. We stopped counting at around 170 cars in the lot when we left.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20052.jpg" rel="lightbox[mt-si]" title="A look back at Mt Si"&gt;&lt;img style="display: block;" title="A look back at Mt Si" border="0" alt="A look back at Mt Si" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/Mount%20Si%20052_thumb.jpg" width="558" height="420" /&gt;&lt;/a&gt;This is one last look at Mt Si on our way back home. Eilon put together a play-by-play using &lt;a title="Birds Eye View of Mt Si" href="http://www.wired.com/gaming/gamingreviews/magazine/17-04/mf_settlers"&gt;Live Maps Bird’s Eye view&lt;/a&gt; (click for larger).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/haystack_2.jpg" rel="lightbox[mt-si]" title="The path we took"&gt;&lt;img style="display: block;" title="The path we took" border="0" alt="The path we took" src="http://haacked.com/images/haacked_com/WindowsLiveWriter/PaniconMtSi_1331F/haystack_thumb.jpg" width="558" height="364" /&gt;&lt;/a&gt;For more info on the Mt Si hike, check out the &lt;a title="hiking mt si" href="http://www.wta.org/go-hiking/hikes/mount-si"&gt;Washington Trails Association website&lt;/a&gt;.&lt;/p&gt;  &lt;div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:cba98a48-e4c3-4232-b8e6-575229cbfb98" class="wlWriterEditableSmartContent"&gt;Tags: &lt;a href="http://haacked.com.com/tags/Hiking/default.aspx" title="Hiking tag" rel="tag"&gt;Hiking&lt;/a&gt;&lt;/div&gt;&lt;img src="http://haacked.com/aggbug/18619.aspx" width="1" height="1" /&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/haacked?a=grt8Py2qyr8:41hgAbmC1r8:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=grt8Py2qyr8:41hgAbmC1r8:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=grt8Py2qyr8:41hgAbmC1r8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?i=grt8Py2qyr8:41hgAbmC1r8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/haacked?a=grt8Py2qyr8:41hgAbmC1r8:G79ilh31hkQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/haacked?d=G79ilh31hkQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
            <dc:creator>Haacked</dc:creator>
            <guid isPermaLink="false">http://haacked.com/archive/2009/05/24/panic-mt-si.aspx</guid>
            <pubDate>Mon, 25 May 2009 03:28:19 GMT</pubDate>
            <wfw:comment>http://haacked.com/comments/18619.aspx</wfw:comment>
            <comments>http://haacked.com/archive/2009/05/24/panic-mt-si.aspx#feedback</comments>
            <slash:comments>29</slash:comments>
            <wfw:commentRss>http://haacked.com/comments/commentRss/18619.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
