<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="http://feeds.feedburner.com/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Adam Tybor's Blog</title>
	
	<link>http://abombss.com</link>
	<description>Abstract &amp;&amp; Concrete</description>
	<pubDate>Sun, 07 Dec 2008 20:36:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.5</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/abombss" type="application/rss+xml" /><item>
		<title>I am on Twitter</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/277424922/</link>
		<comments>http://abombss.com/blog/2008/04/25/i-am-on-twitter/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 06:15:51 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2008/04/25/i-am-on-twitter/</guid>
		<description><![CDATA[So those persuasive alt.net guys finally nudged me to get a twitter account.&#160; Last conference I came home and started a blog, this time its twitter.&#160; As long as its not naked jazz they can persuade me to do just about anything.&#160; They almost got me to get rid of my RDBMS.
]]></description>
			<content:encoded><![CDATA[<p>So those persuasive alt.net guys finally nudged me to get a twitter <a href="http://twitter.com/adamtybor" onclick="javascript:pageTracker._trackPageview('/outbound/article/twitter.com');" target="_blank">account</a>.&nbsp; Last conference I came home and <a href="http://abombss.com"  target="_blank">started a blog</a>, this time its <a href="http://twitter.com/adamtybor" onclick="javascript:pageTracker._trackPageview('/outbound/article/twitter.com');" target="_blank">twitter</a>.&nbsp; As long as its not naked jazz they can persuade me to do just about anything.&nbsp; <a href="http://abombss.com/blog/2008/04/24/alt-dot-net-conf-part-2/"  target="_blank">They almost got me to get rid of my RDBMS</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=hq9meF.p"><img src="http://feeds.feedburner.com/~f/abombss?i=hq9meF.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=oWbdY7.P"><img src="http://feeds.feedburner.com/~f/abombss?i=oWbdY7.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=c4s859.p"><img src="http://feeds.feedburner.com/~f/abombss?i=c4s859.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=nOoJnx.P"><img src="http://feeds.feedburner.com/~f/abombss?i=nOoJnx.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2008/04/25/i-am-on-twitter/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2008/04/25/i-am-on-twitter/</feedburner:origLink></item>
		<item>
		<title>alt.net part II</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/277424923/</link>
		<comments>http://abombss.com/blog/2008/04/24/alt-dot-net-conf-part-2/#comments</comments>
		<pubDate>Fri, 25 Apr 2008 03:00:12 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[Technology]]></category>

		<category><![CDATA[altdotnet]]></category>

		<category><![CDATA[altdotnetconf]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2008/04/24/alt-dot-net-conf-part-2/</guid>
		<description><![CDATA[So better late than never.  Alt.Net Seattle was awesome!  Last October, Austin set the bar high and Seattle blew it away.  The best part was all the new faces at the conference.  The community has really grown and evolved since Austin which made the experience all the more refreshing and interesting.
It [...]]]></description>
			<content:encoded><![CDATA[<p>So better late than never.  <a href="http://altdotnet.org/events/seattle" onclick="javascript:pageTracker._trackPageview('/outbound/article/altdotnet.org');" target="_blank">Alt.Net Seattle</a> was awesome!  Last October, <a href="http://www.altnetconf.com/home" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.altnetconf.com');" title="October 5th 2007 alt.net conference Austin, TX" target="_blank">Austin</a> set the bar high and Seattle blew it away.  The best part was all the new faces at the conference.  The community has really grown and evolved since Austin which made the experience all the more refreshing and interesting.</p>
<p>It was great to get a chance to see guys I haven&#8217;t seen in a while like: <a href="http://weblogs.asp.net/rosherove/" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" title="Roy" target="_blank">Roy</a>, <a href="http://codeprairie.net/blogs/chrisortman/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codeprairie.net');" title="Chris Ortman's Blog" target="_blank">Chris</a>, <a href="http://geekswithblogs.net/dsellers/Default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/geekswithblogs.net');" title="Dru Sellers" target="_blank">Dru</a>, <a href="http://elegantcode.com/about/jason-grundy/" onclick="javascript:pageTracker._trackPageview('/outbound/article/elegantcode.com');" title="Jason Grundy" target="_blank">Jason</a>, <a href="http://codebetter.com/blogs/jeremy.miller/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" title="The Shade Tree Developer: Jeremy Miller's Blog" target="_blank">Jeremy</a>, <a href="http://codebetter.com/blogs/david_laribee/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" title="The Bee Blog: Dave Laribee" target="_blank">Dave</a>, and that crazy posse known as the &#8220;<a href="http://codebetter.com/blogs/aaron.jensen/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" title="Aaron Jensen" target="_blank">Eleutian</a> <a href="http://codebetter.com/blogs/jacob.lewallen/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" title="Jacob Lewallen" target="_blank">Guys</a>&#8220;.  I also had the opportunity to meet tons of new people including <a href="http://www.linkedin.com/in/adymitruk" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.linkedin.com');" target="_blank">Adam Dymitruk</a>, <a href="http://subjunctive.wordpress.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/subjunctive.wordpress.com');" target="_blank">Chris Sutton</a>, <a href="http://www.scottcreynolds.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.scottcreynolds.com');" target="_blank">Scott Reynolds</a>, <a href="http://www.timbarcz.com/blog/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.timbarcz.com');" target="_blank">Tim Barcz</a>, and <a href="http://codebetter.com/blogs/gregyoung/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">Greg Young</a>. (If I left your name out I blame Greg as he <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/09/dddd-1-when-to-message.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">overloaded</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/11/dddd-2-messaging-and-the-ubiquitous-language.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">my</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/11/dddd-3-what-why-this.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">brain</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/14/dddd-4-messages-are-value-objects.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">with</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/15/dddd-5-messages-have-fluent-builders.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">this</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/16/dddd-6-fluent-builders-alternate-ending.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">double</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/22/dddd-7-wow.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">double</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/22/dddd-8-fluent-builders-and-tests.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">d</a> <a href="http://codebetter.com/blogs/gregyoung/archive/2008/04/25/altdotnet-seattle-session-video.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">stuff</a>).</p>
<p>Listening to <a href="http://codebetter.com/blogs/gregyoung/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">Greg</a> and <a href="http://udidahan.weblogs.us/" onclick="javascript:pageTracker._trackPageview('/outbound/article/udidahan.weblogs.us');" title="Udi Dahan" target="_blank">Udi</a> talk about distributed messaging was fascinating.  The idea of using asynchronous messaging and moving away from traditional request / response style of programming is something that I want to learn and work into my applications.  I am not quite ready throw out my RDBMS but thinking about it as just &#8220;Dead Object Storage&#8221; is much more fun.  I need to engage Adam Dymitruk to talk more about how his team made the transition to asynchronous messaging.  He said with some of Greg&#8217;s help it was pretty painless and the benefits the team has seen are huge.</p>
<p>I made sure I left time to hang out after the conference was over this time.  A number of people hung around for a while as well, of course the conversations continued through lunch, over to the book store, and back to the hotel.  By 8pm on Sunday I was dead, I could only imagine what the guys who went to both the MVP Summit and alt.net felt like.  Thanks to <a href="http://weblogs.asp.net/rosherove/" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">Roy</a>, and <a href="http://www.typemock.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.typemock.com');" target="_blank">TypeMock</a> the stragglers got treated to one final meal where yes, more geek speak was spoken.  <a href="http://www.stevenlist.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.stevenlist.com');" target="_blank">Doc</a> and I had a chance to talk for a while at dinner, he did another amazing job facilitating the conference.</p>
<p>So what&#8217;s next&#8230;</p>
<p>Scott Bellware spoke of organizing another alt.net like conference in Austin around October 10th or so.</p>
<p><a href="http://www.hanselman.com/blog/ALTNETGeekCodeShouldYouCareAboutTheseALTNETGuys.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.hanselman.com');" target="_blank">Scott Hanselman posted a nice piece about the alt.net community in general</a>.</p>
<p>Last night here in Chicago we had our 3rd alt.net meeting.  <a href="http://devlicio.us/blogs/derik_whittaker/" onclick="javascript:pageTracker._trackPageview('/outbound/article/devlicio.us');" title="Derik Whittaker" target="_blank">Derik</a> has a <a href="http://devlicio.us/blogs/derik_whittaker/archive/2008/04/24/chicago-alt-net-meeting-review-for-april-23rd.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/devlicio.us');" title="April 23rd Chicago alt.net notes" target="_blank">summary</a> of the <a href="http://tech.groups.yahoo.com/group/ChicagoAltNet/message/49" onclick="javascript:pageTracker._trackPageview('/outbound/article/tech.groups.yahoo.com');" title="April 23rd Chicago alt.net metting notes on yahoo" target="_blank">meeting</a> on the <a href="http://tech.groups.yahoo.com/group/ChicagoAltNet/" onclick="javascript:pageTracker._trackPageview('/outbound/article/tech.groups.yahoo.com');" title="Chicago alt.net yahoo mailing list" target="_blank">yahoo group</a>.  If you are interested in writing better software, getting rid of some of that daily developer pain, or just knocking back a couple beers with some local devs I encourage you come to the next meeting.</p>
<p>Thanks again <a href="http://codebetter.com/blogs/david_laribee/" onclick="javascript:pageTracker._trackPageview('/outbound/article/codebetter.com');" target="_blank">Dave</a> and the rest the organizers for putting this one together.  And a special thanks to the sponsors, <a href="http://www.digipen.edu" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.digipen.edu');" target="_blank">Digipen</a>, <a href="http://www.infoq.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.infoq.com');" target="_blank">InfoQ</a>, <a href="http://msdn2.microsoft.com/en-us/practices/" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');" target="_blank">Microsoft P&amp;P</a>, <a href="http://www.thoughtworks.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.thoughtworks.com');" target="_blank">ThoughtWorks</a>, and <a href="http://www.versionone.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.versionone.com');" target="_blank">VersionOne</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=FQoTKI.p"><img src="http://feeds.feedburner.com/~f/abombss?i=FQoTKI.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=o9H9fE.P"><img src="http://feeds.feedburner.com/~f/abombss?i=o9H9fE.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=GYyQ5c.p"><img src="http://feeds.feedburner.com/~f/abombss?i=GYyQ5c.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=kX1jkv.P"><img src="http://feeds.feedburner.com/~f/abombss?i=kX1jkv.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2008/04/24/alt-dot-net-conf-part-2/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2008/04/24/alt-dot-net-conf-part-2/</feedburner:origLink></item>
		<item>
		<title>Eleutian Vim Screencast Episode #1</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/219075210/</link>
		<comments>http://abombss.com/blog/2008/01/18/eleutian-vim-screencast-episode-1/#comments</comments>
		<pubDate>Fri, 18 Jan 2008 21:27:01 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2008/01/18/eleutian-vim-screencast-episode-1/</guid>
		<description><![CDATA[After Aaron&#8217;s teaser on vim, I have been waiting for him to start the series.  Episode #1 of Aaron&#8217;s Vim screencast series is up.  Its a basic intro for opening and saving documents as well as learning to use some simple navigation.  The use of keyboard jedi is very nice for seeing [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://abombss.com/blog/2007/12/13/vim-screencast-teaser/"  title="Aaron Jensen's Vim Screencast Teaser">After Aaron&#8217;s teaser on vim</a>, I have been waiting for him to start the series.  <a href="http://blog.eleutian.com/2008/01/18/VimScreencast1.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blog.eleutian.com');" title="Eleutian Vim Screencast: Episode #1" target="_blank">Episode #1 of Aaron&#8217;s Vim screencast series is up</a>.  Its a basic intro for opening and saving documents as well as learning to use some simple navigation.  The use of keyboard jedi is very nice for seeing everything that is going on.  Nice work Aaron!  If you are unfamiliar with vim I highly recommend subscribing to <a href="http://blog.eleutian.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/blog.eleutian.com');" title="Eleutian Blog" target="_blank">Eleutian&#8217;s blog</a> and following the series.  The productivity boost you will gain down the road is priceless.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=aDSjCz.p"><img src="http://feeds.feedburner.com/~f/abombss?i=aDSjCz.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=W5DcE7.P"><img src="http://feeds.feedburner.com/~f/abombss?i=W5DcE7.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=I9xdQu.p"><img src="http://feeds.feedburner.com/~f/abombss?i=I9xdQu.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=9zOawj.P"><img src="http://feeds.feedburner.com/~f/abombss?i=9zOawj.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2008/01/18/eleutian-vim-screencast-episode-1/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2008/01/18/eleutian-vim-screencast-episode-1/</feedburner:origLink></item>
		<item>
		<title>Ms MVC at CNUG</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/218129084/</link>
		<comments>http://abombss.com/blog/2008/01/17/ms-mvc-at-cnug/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 08:53:43 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[cnug]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2008/01/17/ms-mvc-at-cnug/</guid>
		<description><![CDATA[Yesterday at the Chicago .Net User Group meeting Nermin Dibek presented on the new ms mvc framework.  Several people were interested in a follow up session.  If you are one of those people and have stumbled onto this blog, or if you are local to Chicago and want to see some more stuff, feel free [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday at the Chicago .Net User Group meeting <a href="http://www.nermins.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.nermins.net');" title="Nermin Dibek's Blog" target="_blank">Nermin Dibek</a> presented on the new ms mvc framework.  Several people were interested in a follow up session.  If you are one of those people and have stumbled onto this blog, or if you are local to Chicago and want to see some more stuff, feel free to ping me or email me and we can try and set something up.</p>
<p>Here is a list of links to get you started with Ms MVC.</p>
<ul>
<li><a href="http://www.asp.net/downloads/3.5-extensions/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.asp.net');">http://www.asp.net/downloads/3.5-extensions/</a> (The bits)</li>
<li><a href="http://mvccontrib.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/mvccontrib.org');">http://mvccontrib.org</a> (mvc contrib.)</li>
<li><a href="http://forums.asp.net/1146.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/forums.asp.net');">http://forums.asp.net/1146.aspx</a> (asp.net mvc forums)</li>
<li><a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');">http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-mvc-framework-part-4-handling-form-edit-and-post-scenarios.aspx</a> (Part 4 of a great series by ScottGu, links to part 1,2,3 included)</li>
<li><a href="http://www.dotnetrocks.com/default.aspx?showNum=299" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.dotnetrocks.com');">http://www.dotnetrocks.com/default.aspx?showNum=299</a> (podcast)</li>
<li><a href="http://dnrtv.com/default.aspx?showID=95" onclick="javascript:pageTracker._trackPageview('/outbound/article/dnrtv.com');">http://dnrtv.com/default.aspx?showID=95</a> (screencast)</li>
<li><a href="http://del.icio.us/search/?fr=del_icio_us&amp;p=aspnetmvc&amp;type=all" onclick="javascript:pageTracker._trackPageview('/outbound/article/del.icio.us');" title="http://del.icio.us/search/?fr=del_icio_us&amp;p=aspnetmvc&amp;type=all">http://del.icio.us/search/?fr=del_icio_us&amp;p=aspnetmvc&amp;type=all</a> (links on del.icio.us)</li>
</ul>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=IhEodm.p"><img src="http://feeds.feedburner.com/~f/abombss?i=IhEodm.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=cM198R.P"><img src="http://feeds.feedburner.com/~f/abombss?i=cM198R.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=jczgH5.p"><img src="http://feeds.feedburner.com/~f/abombss?i=jczgH5.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=0H1CdP.P"><img src="http://feeds.feedburner.com/~f/abombss?i=0H1CdP.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2008/01/17/ms-mvc-at-cnug/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2008/01/17/ms-mvc-at-cnug/</feedburner:origLink></item>
		<item>
		<title>MS MVC: Blocks Refactored</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/218116030/</link>
		<comments>http://abombss.com/blog/2008/01/17/ms-mvc-blocks-refactored/#comments</comments>
		<pubDate>Thu, 17 Jan 2008 08:34:50 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2008/01/17/ms-mvc-blocks-refactored/</guid>
		<description><![CDATA[In my last post I talked about adding blocks to ms mvc to capture output.  Our solution used an ugly hack with reflection, type caching, and lwg.  Thanks to Jeremy Skinner and Phil who both pointed out you can use a response output filter to do the same thing.  So here is an update to [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post I talked about <a href="http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/"  title="Rails like Blocks in MS MVC" target="_blank">adding blocks to ms mvc to capture output</a>.  Our solution used an ugly hack with reflection, type caching, and <a href="http://msdn2.microsoft.com/en-us/library/system.reflection.emit.dynamicmethod.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');" title="DynamicMethod : Light Weight Code Generation" target="_blank">lwg</a>.  Thanks to Jeremy Skinner and <a href="http://haacked.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/haacked.com');" title="Haacked : Phil Haacks Blog" target="_blank">Phil</a> who both pointed out you can use a response output filter to do the same thing.  So here is an update to our capturing class.</p>
<pre><span style="color: #808080">/// &lt;summary&gt;Renders the action and returns a string.&lt;/summary&gt;</span>
<span style="color: #808080">/// &lt;param name="viewRenderer"&gt;The delegate to render.&lt;/param&gt;</span>
<span style="color: #808080">/// &lt;returns&gt;The rendered text.&lt;/returns&gt;</span>
<span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Capture(Action viewRenderer)
{
  IHttpResponse resp = _httpContext.Response;
  Stream originalFilter = <span style="color: #0000ff">null</span>;
  CapturingResponseFilter innerFilter;
  <span style="color: #0000ff">string</span> capturedHtml = "<span style="color: #8b0000"></span>";

  <span style="color: #0000ff">if</span> (viewRenderer != <span style="color: #0000ff">null</span>)
  {
    <span style="color: #0000ff">try</span>
    {
      resp.Flush();
      originalFilter = resp.Filter;
      innerFilter = <span style="color: #0000ff">new</span> CapturingResponseFilter(resp.Filter);
      resp.Filter = innerFilter;
      viewRenderer();
      resp.Flush();
      capturedHtml = innerFilter.GetContents(resp.ContentEncoding);
    }
    <span style="color: #0000ff">finally</span>
    {
      <span style="color: #0000ff">if</span> (originalFilter != <span style="color: #0000ff">null</span>)
      {
        resp.Filter = originalFilter;
      }
    }
  }
  <span style="color: #0000ff">return</span> capturedHtml;
}</pre>
<p>The only thing to remember is to flush current response before and after you capture the text.  The CapturingResponseFilter just inherits from Stream and is using a MemoryStream internally.  The call to GetContents just dumps the memory stream to a string using the current encoding of the response.</p>
<p>What do you think&#8230; much simpler <img src='http://abombss.com/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Thanks Jeremy and Phil.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=SXhl0u.p"><img src="http://feeds.feedburner.com/~f/abombss?i=SXhl0u.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=TUIAvv.P"><img src="http://feeds.feedburner.com/~f/abombss?i=TUIAvv.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=LUBm14.p"><img src="http://feeds.feedburner.com/~f/abombss?i=LUBm14.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=XOTR5s.P"><img src="http://feeds.feedburner.com/~f/abombss?i=XOTR5s.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2008/01/17/ms-mvc-blocks-refactored/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2008/01/17/ms-mvc-blocks-refactored/</feedburner:origLink></item>
		<item>
		<title>MS MVC Gets Blocks From Rails</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/207829987/</link>
		<comments>http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/#comments</comments>
		<pubDate>Sat, 29 Dec 2007 02:13:57 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/</guid>
		<description><![CDATA[Updated 2008-01-16:
Check out the refactored version which drops the reflection and uses a straight response filter.
Sergio Pereira and I started writing some stories today for Javascript helpers in Mvc Contrib.  During our talk we had to deal with rendering html elements with inner html and javascript blocks ensuring they all got closed but still allowing [...]]]></description>
			<content:encoded><![CDATA[<p class="edit"><strong>Updated 2008-01-16:</strong></p>
<p><a href="http://abombss.com/blog/2008/01/17/ms-mvc-blocks-refactored/"  title="Ms Mvc Rails like Blocks Refactored" target="_blank">Check out the refactored version which drops the reflection and uses a straight response filter.</a></p>
<hr />Sergio Pereira and I started writing some stories today for Javascript helpers in Mvc Contrib.  During our talk we had to deal with rendering html elements with inner html and javascript blocks ensuring they all got closed but still allowing the ultimate in flexibility for the developer.MvcToolkit goes about this with a using(&#8230;) pattern on their FormHelper.  The one disadvantage of this is that the using block will be limited to only a single block.  What happens when you need to render a block for onSuccess and onFailure?</p>
<p>Sergio brought up how powerful ruby blocks are and how cool it would be if we could use lambdas to do something similar.</p>
<p>Sergio proposed being able to do something like this.</p>
<p>&lt;% Ajax.Tag(&#8221;<span style="color: #8b0000">div</span>&#8220;,  &#8220;<span style="color: #8b0000">/controller/action/123</span>&#8220;,<br />
<span style="color: #0000ff">new</span> {CssClass=&#8221;<span style="color: #8b0000">bigSquare</span>&#8220;}, myDiv =&gt;<br />
{ %&gt;<br />
Some Html here<br />
Some helper: &lt;%= Html.Link(&#8221;<span style="color: #8b0000">Click me</span>&#8220;, &#8220;<span style="color: #8b0000">/other/non-ajax/url</span>&#8220;) %&gt;<br />
}) %&gt;</p>
<p>What is myDiv?  myDiv is the blocks outer HtmlElement object so inside of your lambda you can manipulate its attributes and perform some other cool stuff we are still cooking up.  While the lambda executes we capture the output and defer rendering to the response until after the lambda is finished.  This allows us to render the HtmlElement with any modifications you made.</p>
<p>So how do we do this, well, we needed a pretty big hack because our delegate is being called from another anonymous delegate which has the HtmlTextWriter as a local variable.  This means that we cannot use IHttpContext.SwitchWriter to capture our output.</p>
<p><strong>Any way to get a fix for this MS?</strong></p>
<p>So in reflector I noticed my anonymous type for my delegate had a public field __w which was the HtmlTextWriter.  Using some reflection I was able to code up my own SwitchWriter which took care of everything.</p>
<p>The helper code is pretty simple.</p>
<pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> FromTag(<span style="color: #0000ff">this</span> AjaxHelper helper
  ,<span style="color: #0000ff">string</span> tag
  ,<span style="color: #0000ff">string</span> url
  ,<span style="color: #0000ff">object</span> options,
  Action&lt;Element&gt; innerHtml)
{
  Element element = <span style="color: #0000ff">new</span> Element(tag);
  HtmlTextWriter responseWriter = <span style="color: #0000ff">null</span>;

  <span style="color: #0000ff">if</span>(innerHtml != <span style="color: #0000ff">null</span>)
  {
      <span style="color: #0000ff">try</span>
      {
        <span style="color: #0000ff">using</span>(StringWriter innerWriter = <span style="color: #0000ff">new</span> StringWriter())
        <span style="color: #0000ff">using</span> (HtmlTextWriter innerHtmlWriter =
          <span style="color: #0000ff">new</span> HtmlTextWriter(innerWriter))
        {
          responseWriter = SwitchWriter(innerHtml, innerHtmlWriter);
          innerHtml(element);
          innerHtmlWriter.Flush();
          element.InnerHtml = innerWriter.ToString();
        }
      }
      <span style="color: #0000ff">finally</span>
      {
        <span style="color: #0000ff">if</span>(responseWriter != <span style="color: #0000ff">null</span>)
        {
          SwitchWriter(innerHtml, responseWriter);
        }
      }
  }
  RenderElement(<span style="color: #0000ff">new</span> HtmlTextWriter(
    helper.ViewContext.HttpContext.Response.Output), element);
}</pre>
<p>The switch writer is pretty basic, it was tracking it down that took a little bit of time.</p>
<pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> HtmlTextWriter SwitchWriter(<span style="color: #0000ff">object</span> obj
  , HtmlTextWriter newWriter)
{
  Type actionType = obj.GetType();

  <span style="color: #0000ff">object</span> target = actionType.GetField("<span style="color: #8b0000">_target</span>",
    BindingFlags.NonPublic | BindingFlags.Instance)
    .GetValue(obj);

  Type targetType = target.GetType();

  HtmlTextWriter response = targetType.GetField("<span style="color: #8b0000">__w</span>")
    .GetValue(target) <span style="color: #0000ff">as</span> HtmlTextWriter;

  targetType.GetField("<span style="color: #8b0000">__w</span>").SetValue(target, newWriter);

  <span style="color: #0000ff">return</span> response;
}</pre>
<p>With the above in place I can call it with something like this.</p>
<pre>&lt;% Ajax.FromTag("<span style="color: #8b0000">div</span>", "<span style="color: #8b0000">/Home/About</span>",
  <span style="color: #0000ff">new</span> <span style="color: #0000ff">object</span>(),
  myDiv =&gt; { myDiv.Id = "<span style="color: #8b0000">Justice</span>"; %&gt;&lt;h6&gt;
      &lt;%=Html.ActionLink("<span style="color: #8b0000">Where is Justice?</span>", "<span style="color: #8b0000">About</span>")%&gt;
   &lt;/h6&gt;
&lt;% }); %&gt;</pre>
<p>And it renders something like this&#8230; no we didn&#8217;t spike any ajax stuff yet.</p>
<pre><span style="color: #0000ff">&lt;</span><span style="color: #800000">div</span> <span style="color: #ff0000">id</span>=<span style="color: #0000ff">"Justice"</span><span style="color: #0000ff">&gt;</span>
 <span style="color: #0000ff">&lt;</span><span style="color: #800000">h6</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">a</span> <span style="color: #ff0000">href</span>=<span style="color: #0000ff">"/Home/About"</span><span style="color: #0000ff">&gt;</span>Where is Justice?<span style="color: #0000ff">&lt;/</span><span style="color: #800000">a</span><span style="color: #0000ff">&gt;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">h6</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">div</span><span style="color: #0000ff">&gt;</span></pre>
<p>You may wonder why we do not return a string from our helper.  Asp.Net currently can&#8217;t handle that.  It thinks its a block and not a simple expression so using the regular &lt;%= %&gt; will not work.  Instead of having you call &lt;%Response.Write(&#8230;);%&gt; we thought it would be easier if the helper just rendered it for you.</p>
<p>This got me excited about some the cool things we can really start to do.  I like getting an instance of Element to set properties on, this can help reduce the abuse that anonymous types are taking in mvc right now.  It would be great if there could be patch so we do not have to resort to reflection to switch writers, but I quote Sergio</p>
<blockquote><p>how do you feel about that __w hack? For me it looks prettier by the minute</p></blockquote>
<p>Let me know what you think,</p>
<p>Cheers</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=j4b9Y5.p"><img src="http://feeds.feedburner.com/~f/abombss?i=j4b9Y5.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=84jesm.P"><img src="http://feeds.feedburner.com/~f/abombss?i=84jesm.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=0k18AX.p"><img src="http://feeds.feedburner.com/~f/abombss?i=0k18AX.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=g42Jcv.P"><img src="http://feeds.feedburner.com/~f/abombss?i=g42Jcv.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/28/ms-mvc-gets-blocks-from-rails/</feedburner:origLink></item>
		<item>
		<title>Browser Wars are Heating Up</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/203244863/</link>
		<comments>http://abombss.com/blog/2007/12/20/browser-wars-are-heating-up/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 07:18:08 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<category><![CDATA[ie]]></category>

		<category><![CDATA[news]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/20/browser-wars-are-heating-up/</guid>
		<description><![CDATA[Looks like IE8 can render the acid2 face test.  Nice work IE team, maybe we will start seeing more releases out of Microsoft with some higher quality.  Today, Jeff talks about the javascript showdown between browsers.  I agree with him, competition is a good thing.
Now if I could only get a FF [...]]]></description>
			<content:encoded><![CDATA[<p>Looks like <a href="http://blogs.msdn.com/ie/archive/2007/12/19/internet-explorer-8-and-acid2-a-milestone.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');" title="Internet Explorer 8 Can Render Acid2 Test" target="_blank">IE8</a> can render the <a href="http://www.webstandards.org/action/acid2/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.webstandards.org');" target="_blank">acid2 face</a> test.  Nice work IE team, maybe we will start seeing more releases out of Microsoft with some higher quality.  Today, <a href="http://codinghorror.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/codinghorror.com');" title="Coding Horror: A Blog by Jeff Atwood" target="_blank">Jeff</a> talks about the <a href="http://www.codinghorror.com/blog/archives/001023.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.codinghorror.com');" title="The Great Browser JavaScript Showdown" target="_blank">javascript showdown</a> between browsers.  I agree with him, competition is a good thing.</p>
<p>Now if I could only get a FF 2.0 and FF 3.0 side by side install going.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=5NNTYo.p"><img src="http://feeds.feedburner.com/~f/abombss?i=5NNTYo.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=PDsEu1.P"><img src="http://feeds.feedburner.com/~f/abombss?i=PDsEu1.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=jXJvyo.p"><img src="http://feeds.feedburner.com/~f/abombss?i=jXJvyo.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=zFgLSZ.P"><img src="http://feeds.feedburner.com/~f/abombss?i=zFgLSZ.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/20/browser-wars-are-heating-up/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/20/browser-wars-are-heating-up/</feedburner:origLink></item>
		<item>
		<title>Haml Comes to MS MVC</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/203169088/</link>
		<comments>http://abombss.com/blog/2007/12/19/haml-comes-to-ms-mvc/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 04:22:53 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/19/haml-comes-to-ms-mvc/</guid>
		<description><![CDATA[Andrew Peter has created NHaml, a new view engine for MS MVC based on the ruby Haml dsl.  Sweet!!  Maybe we can get Andrew to drop this in the MVC Contrib project.
The community support for MS MVC has been awesome so far.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://andrewpeters.net/" onclick="javascript:pageTracker._trackPageview('/outbound/article/andrewpeters.net');" title="Andrew Peter's Blog" target="_blank">Andrew Peter</a> has created <a href="http://andrewpeters.net/2007/12/19/introducing-nhaml-an-aspnet-mvc-view-engine/" onclick="javascript:pageTracker._trackPageview('/outbound/article/andrewpeters.net');" title="NHaml and Ruby Haml Inspired View Engine for MS MVC" target="_blank">NHaml</a>, a new view engine for MS MVC based on the ruby <a href="http://haml.hamptoncatlin.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/haml.hamptoncatlin.com');" title="Ruby Haml DSL">Haml dsl</a>.  Sweet!!  Maybe we can get Andrew to drop this in the <a href="http://mvccontrib.org" onclick="javascript:pageTracker._trackPageview('/outbound/article/mvccontrib.org');" title="Microsoft Mvc Contrib Project" target="_blank">MVC Contrib</a> project.</p>
<p>The community support for MS MVC has been awesome so far.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=BsiLr0.p"><img src="http://feeds.feedburner.com/~f/abombss?i=BsiLr0.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=K6eaTg.P"><img src="http://feeds.feedburner.com/~f/abombss?i=K6eaTg.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=PlCfS6.p"><img src="http://feeds.feedburner.com/~f/abombss?i=PlCfS6.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=SqEBas.P"><img src="http://feeds.feedburner.com/~f/abombss?i=SqEBas.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/19/haml-comes-to-ms-mvc/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/19/haml-comes-to-ms-mvc/</feedburner:origLink></item>
		<item>
		<title>MS MVC: Routing - The Good, The Bad, The RESTful</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/203126824/</link>
		<comments>http://abombss.com/blog/2007/12/19/ms-mvc-routing-the-good-the-bad-the-restful/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 02:35:00 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[routing]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/19/ms-mvc-routing-the-good-the-bad-the-restful/</guid>
		<description><![CDATA[After playing with MS MVC for a little bit, and looking at routing extensively I have compiled a list of good things and things that need some improvement.  The team has already said they will be doing work with routing, I am looking forward to seeing what they come up with.
What&#8217;s Good with MS [...]]]></description>
			<content:encoded><![CDATA[<p>After playing with MS MVC for a little bit, and looking at routing extensively I have compiled a list of good things and things that need some improvement.  The team has already said they will be doing work with routing, I am looking forward to seeing what they come up with.</p>
<h2>What&#8217;s Good with MS MVC Routing?</h2>
<h3>Not Bound Explicitly To Controllers and Actions</h3>
<p>An innovative approach to routing was not forcing the controller and action to be bound to the route.  Instead they introduced two special parameters [controller] and [action] to indirectly bind the request.  This drastically reduces the number of routes your application needs and means you do not have to register a route for every new controller.</p>
<h3>Validation</h3>
<p>Validation separates the url from matching on the parameters.  It allows for full blown regular expressions without dirtying up the url and making it more difficult to generate urls from the routes.  <a href="http://hammett.castleproject.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/hammett.castleproject.org');" title="Hamilton Verissimo's Blog" target="_blank">Hammett</a> ran into this issue with his <a href="http://hammett.castleproject.org/?p=216" onclick="javascript:pageTracker._trackPageview('/outbound/article/hammett.castleproject.org');" target="_blank">new routing module for monorail</a> when he offered a straight regex rule.  There was no way to pull parameters out of it.</p>
<h3>Route Handlers</h3>
<p>A very simple way to <a href="http://weblogs.asp.net/fredriknormen/archive/2007/11/18/asp-net-mvc-framework-create-your-own-iroutehandler.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">extend route resolution</a> <a href="http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/"  target="_blank">on incoming requests</a>.  Its not complicated and it gives you access to everything you need to do custom matching.  I wish we could get something like that for generating urls.</p>
<h3>Restful</h3>
<p>Not much more to say <a href="http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/"  title="Adam Tybor's Blog: MS MVC - Simply Restful Routing" target="_blank">hear that</a> <a href="http://blog.wekeroad.com/2007/12/06/aspnet-mvc-using-restful-architecture/" onclick="javascript:pageTracker._trackPageview('/outbound/article/blog.wekeroad.com');" title="Rob Conery:  ASP.NET MVC - Using RESTful Architecture" target="_blank">hasn&#8217;t</a> <a href="http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" title="Scott Guthrie's Blog:  ASP.NET MVC Framework (Part 2) - URL Routing" target="_blank">already</a> <a href="http://haacked.com/archive/2007/11/10/the-rest-like-aspect-of-asp.net-mvc.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/haacked.com');" title="Phil Haack's Blog: The REST-Like Aspect Of ASP.NET MVC" target="_blank">been</a> <a href="http://odetocode.com/Blogs/scott/archive/2007/11/11/11554.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/odetocode.com');" title="K. Scott Allen's Blog: MVC, REST, and the Alternative ASP.NET Framework" target="_blank">said</a>.  This engine does make writing restful urls a breeze.</p>
<h3>Testing</h3>
<p>Thank you for making my routes so <a href="http://haacked.com/archive/2007/12/17/testing-routes-in-asp.net-mvc.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/haacked.com');" title="Phil Haack's Blog: Testing Routes In ASP.NET MVC" target="_blank">easy</a> to <a href="http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/"  title="Adam Tybor's Blog: MS MVC: Testing Routes" target="_blank">test</a>.  I now have confidence that everything is working without having to fire up IIS and a browser to test by hand.</p>
<h2>What&#8217;s Not So Good with MS MVC Routing?</h2>
<h3>No Duplicate Controller Names?</h3>
<p>I can&#8217;t have two controllers in different namespaces with the same name?</p>
<h4>Solution</h4>
<p><a href="http://haacked.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/haacked.com');" title="Haacked : Phil Haacks Blog" target="_blank">Phil</a> said <a href="http://forums.asp.net/p/1194576/2061856.aspx#2061193" onclick="javascript:pageTracker._trackPageview('/outbound/article/forums.asp.net');" target="_blank">they are fixing this</a>.  I would hope I could specify a Controller parameter either as a Type or a String where the string could be the full name of the controller.  I would also maybe like this to be addressed with Areas&#8230; <em>maybe</em>.</p>
<h3>Areas Where Are You?</h3>
<p>There is no out of the box support for <a href="http://www.castleproject.org/monorail/documentation/trunk/usersguide/controllerbasics.html#Areas" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.castleproject.org');" title="Castle Project: Monorail -  Controller Basics" target="_blank">Areas</a>.  An area is simply a partition for your application.  The most common one I can think of is http://localhost/admin/[controller] for separating all of your admin stuff from regular url&#8217;s.</p>
<p>Another scenario would be dropping in secondary applications, like a forum, blog, photo gallery, etc.  Those will probably need to be defined under some Area.</p>
<h4>Workarounds</h4>
<pre>RouteTable.Routes.Add(<span style="color: #0000ff">new</span> Route
{
 Url = "<span style="color: #8b0000">admin/[controller]/[action]</span>",
 Defaults = <span style="color: #0000ff">new</span>
 {
  Controller = "<span style="color: #8b0000">Admin</span>",
  Action = "<span style="color: #8b0000">Index</span>"
 },
 Validation = <span style="color: #0000ff">new</span>
 {
  Controller = "<span style="color: #8b0000">Admin|Users|Categories</span>"
 },
 RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});</pre>
<p>What we did above is hard code are &#8220;admin&#8221; area and then set a Validation regular expression on Controller.  Now only the controllers listed will be accessible via those urls, and when generating a url it will have the correct prefix of &#8220;admin/&#8221; in the path.</p>
<p>What sucks about that?  Every time I add a new controller that should be an admin controller I have to modify the regular expression.  BTW, that regex is not case insensitive like the url.</p>
<h4>Potential Solutions</h4>
<ol>
<li>Allow a convention where the namespace dictates the area.</li>
<li>Add an AreaAttribute similar to Monorail.</li>
</ol>
<p>I like having the option of number 1, but I don&#8217;t want to be forced to this.  It makes my urls feel to tightly coupled to my code.  Its not a bad default convention as I am sure it will work the vast majority of the time.</p>
<p>Number 2 just doesn&#8217;t sit right with me but it seems like a decent option as well.  The area has to come from somewhere, right?</p>
<p>One thing is for sure, there needs to be some type of Area parameter that is respected by the RouteCollection and based on the current implementation it looks like it would be very difficult for it to support areas deeper than 1 level.  By default it is splitting on the &#8220;/&#8221; so an area covering &#8220;admin/maintenance&#8221; would be difficult to use with a single Area parameter.</p>
<p>Maybe it could support arrays which could get interesting&#8230;</p>
<pre>[area]/[area]/[area]/[controller]/[action]
Defaults = new { Area = "admin/maintenance/daily" }
Validation = new { Area = "admin/maintenance/daily" }</pre>
<h3>Are We Really Blocking and Locking?</h3>
<p>Reflecting over the code of the RouteCollection we can see that when an operation is performed like GetRouteData or GetUrl then the routes are locked until the proper route is matched.  Every request coming into your application is going to call GetRouteData and every link you render in your views is going to call GetUrl.  What does this mean.  It means when a request comes in it locks the routes searching for a match.  When a new request comes in on a separate thread it calls GetRouteData too and sits and waits until the first request found a match before it can proceed.  And all the blocking happens for every link that you are rendering in your views too.  Most pages will have 10 - 20 links, that&#8217;s lot of blocking, idle time, and context switches for the OS.</p>
<h4>Solution</h4>
<p>Don&#8217;t lock, period.  Adding routes should go into a temp route collection.  Add explicit methods for Build() or Rebuild() which can perform an atomic assignment operation on the temp routes to the routes in use.  Can some kind of error happen if routes are switch in the middle of processing a request? Yes.  What are the odds? Slim.  If dynamically altering routes is something that my application requires, without restarting it, then let me handle that.  Its an edge case.</p>
<p>If you have to lock, think about using a <a href="http://www.boyet.com/Articles/LockfreeFreeList.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.boyet.com');" title="Lock-free data structures: the free list" target="_blank">lock free collection</a>, or use Reader/Writer locks as the number of reads is going to demolish the number of writes.  Locking is just way too expensive to do on every request and every link render.</p>
<h3>Why is Validation Case Sensitive?</h3>
<p>Urls should be case insensitive.  If I want to validate parameters using a regular expression those should be case insensitive to.  Please don&#8217;t make me write Validation expression like: @&#8221;[eE][dD][iI][tT]&#8221; to match any combination of the string &#8220;Edit&#8221;.</p>
<h3>Why is Validation Not Compiled?</h3>
<p>Every request coming in is going to call GetRouteData, does it not make sense to compile my Validation expressions so they do not need to parsed every time they are evaluated?</p>
<h4>Solution</h4>
<pre><span style="color: #0000ff">if</span> (!Regex.IsMatch(input, pattern))
{
 <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>;
}</pre>
<p>to</p>
<pre><span style="color: #0000ff">foreach</span>(Regex validator <span style="color: #0000ff">in</span> route.Validators)
{
 <span style="color: #008000">//...</span>
 <span style="color: #0000ff">if</span>(!validator.IsMatch(input))
 {
  <span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span>;
 }
 <span style="color: #008000">//...</span>
}</pre>
<h3>Where is the Extensibility?</h3>
<p>No, <a href="http://www.ayende.com/Blog/archive/2007/12/17/On-the-faults-of-thinking-It-is-extensible-the-users.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ayende.com');" target="_blank">not this extensibility</a>, well maybe, give me the option please.</p>
<p>There are a number of edge cases popping up on blogs, comments, and forum posts.</p>
<ul>
<li>What do I do if I need a different sub/domain?</li>
<li>What do I do if I need to redirect to a secure url from an insecure one?</li>
<li>What do I do if I need an absolute url instead of a relative one?</li>
<li>What do I do if I need to redirect to a non-standard port for https?</li>
</ul>
<p>While the <strong>MVCRouteHandler</strong> is extendable the <strong>Route</strong> is not, nor is the <strong>RouteCollection</strong>.  We need a way to override the matching AND url generating for specific rules.</p>
<h4>Potential Solution</h4>
<p>The RouteCollection looks a little heavy.  I think it can delegate some of its responsibility to other services whose implementations can be swapped out.  I also think it would be prudent to give us some interfaces and factories.  Just overriding the GetRouteData and GetUrl is not enough. It would be great to have the ability to create our own RouteCollection so we could implement different algorithms for collecting and enumerating the routes to find a match?</p>
<h2>Summary</h2>
<p>All in all I am very pleased with routing in the first CTP.  IMHO it is better than Monorail routing right now.  It does need some pieces re-thought, re-factored, and de-debugged, but if it were perfect it wouldn&#8217;t be CTP and I wouldn&#8217;t be writing this.</p>
<p>Please let me know what I am missing and how crazy some of my solutions are.</p>
<p>+1 To the MS-MVC team, they are off to a great start.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=ERYvOf.p"><img src="http://feeds.feedburner.com/~f/abombss?i=ERYvOf.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=juEX01.P"><img src="http://feeds.feedburner.com/~f/abombss?i=juEX01.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=bXrN20.p"><img src="http://feeds.feedburner.com/~f/abombss?i=bXrN20.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=zmIS8w.P"><img src="http://feeds.feedburner.com/~f/abombss?i=zmIS8w.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/19/ms-mvc-routing-the-good-the-bad-the-restful/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/19/ms-mvc-routing-the-good-the-bad-the-restful/</feedburner:origLink></item>
		<item>
		<title>Vim Screencast Teaser</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/200006253/</link>
		<comments>http://abombss.com/blog/2007/12/13/vim-screencast-teaser/#comments</comments>
		<pubDate>Fri, 14 Dec 2007 00:08:54 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[tips]]></category>

		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/13/vim-screencast-teaser/</guid>
		<description><![CDATA[Aaron just posted a kick ass teaser about using vim.  I want the whole series on dvd now.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.eleutian.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/blog.eleutian.com');" title="Eleutian Development Blog" target="_blank">Aaron</a> just posted a <a href="http://blog.eleutian.com/2007/12/13/VimScreencastTutorialTeaser.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/blog.eleutian.com');" target="_blank">kick ass teaser about using vim</a>.  I want the whole series on dvd now.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=2zftaA.p"><img src="http://feeds.feedburner.com/~f/abombss?i=2zftaA.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=Zj359L.P"><img src="http://feeds.feedburner.com/~f/abombss?i=Zj359L.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=RfKXlj.p"><img src="http://feeds.feedburner.com/~f/abombss?i=RfKXlj.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=X6Dkpa.P"><img src="http://feeds.feedburner.com/~f/abombss?i=X6Dkpa.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/13/vim-screencast-teaser/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/13/vim-screencast-teaser/</feedburner:origLink></item>
		<item>
		<title>Toggle Between Tabs &amp; Spaces With Ease</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/199590647/</link>
		<comments>http://abombss.com/blog/2007/12/12/toggle-between-tabs-spaces-with-ease/#comments</comments>
		<pubDate>Wed, 12 Dec 2007 22:21:25 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[tip]]></category>

		<category><![CDATA[vs2k8]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/12/toggle-between-tabs-spaces-with-ease/</guid>
		<description><![CDATA[Ever get yelled at for using tabs instead of spaces or spaces instead of tabs?&#160; Here&#8217;s your cure it toggles the text editor settings in visual studio for you.
Public Sub ToggleTabsAndSpaces()
 Dim keys As String() = { _
  "Basic", _
  "C/C++", _
  "CSharp", _
  "CSS", _
  "HTML", _
  "PL/SQL", [...]]]></description>
			<content:encoded><![CDATA[<p>Ever get yelled at for using tabs instead of spaces or spaces instead of tabs?&nbsp; Here&#8217;s your cure it toggles the text editor settings in visual studio for you.</p>
<pre><span style="color: #0000ff">Public</span> <span style="color: #0000ff">Sub</span> ToggleTabsAndSpaces()
 <span style="color: #0000ff">Dim</span> keys <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span>() = { _
  "<span style="color: #8b0000">Basic</span>", _
  "<span style="color: #8b0000">C/C++</span>", _
  "<span style="color: #8b0000">CSharp</span>", _
  "<span style="color: #8b0000">CSS</span>", _
  "<span style="color: #8b0000">HTML</span>", _
  "<span style="color: #8b0000">PL/SQL</span>", _
  "<span style="color: #8b0000">PlainText</span>", _
  "<span style="color: #8b0000">T-SQL</span>", _
  "<span style="color: #8b0000">XML</span>"}

 <span style="color: #0000ff">Dim</span> turnTabsOn <span style="color: #0000ff">As</span> <span style="color: #0000ff">Boolean</span> = <span style="color: #0000ff">True</span>
 <span style="color: #0000ff">Dim</span> msg = "<span style="color: #8b0000">Truning Tabs On</span>"

 <span style="color: #0000ff">If</span> DTE.Properties("<span style="color: #8b0000">TextEditor</span>", keys(0)) _
   .Item("<span style="color: #8b0000">InsertTabs</span>").Value = <span style="color: #0000ff">True</span> <span style="color: #0000ff">Then</span>
   turnTabsOn = <span style="color: #0000ff">False</span>
   msg = "<span style="color: #8b0000">Turning Tabs Off</span>"
 <span style="color: #0000ff">End</span> <span style="color: #0000ff">If</span>

 IdeHelper.StatusBar(msg)
 IdeHelper.Output(msg)

 <span style="color: #0000ff">With</span> DTE.Properties("<span style="color: #8b0000">TextEditor</span>", "<span style="color: #8b0000">AllLanguages</span>")
   .Item("<span style="color: #8b0000">TabSize</span>").Value = 2
   .Item("<span style="color: #8b0000">InsertTabs</span>").Value = 2
 <span style="color: #0000ff">End</span> <span style="color: #0000ff">With</span>

 <span style="color: #0000ff">For</span> <span style="color: #0000ff">Each</span> key <span style="color: #0000ff">As</span> <span style="color: #0000ff">String</span> <span style="color: #0000ff">In</span> keys
   DTE.Properties("<span style="color: #8b0000">TextEditor</span>", key) _
   .Item("<span style="color: #8b0000">InsertTabs</span>").Value = turnTabsOn
 <span style="color: #0000ff">Next</span>
<span style="color: #0000ff">End</span> <span style="color: #0000ff">Sub</span></pre>
<p>I mapped mine to Ctrl+Shift+=</p>
<p>If you need to find out what the names of the different editors are you can look them up in the registry.</p>
<dl>
<dt>x64</dt>
<dd><code>HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\AutomationProperties\TextEditor</code></dd>
<dt>x32</dt>
<dd><code>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\AutomationProperties\TextEditor</code></dd>
</dl>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:1211b9e6-dff2-49df-aaab-55ba5c0c0f38" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">[tag]vs2k8, tip[/tag]</div>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=E8mvaF.p"><img src="http://feeds.feedburner.com/~f/abombss?i=E8mvaF.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=nTp6YB.P"><img src="http://feeds.feedburner.com/~f/abombss?i=nTp6YB.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=C6FOw1.p"><img src="http://feeds.feedburner.com/~f/abombss?i=C6FOw1.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=hIXEk6.P"><img src="http://feeds.feedburner.com/~f/abombss?i=hIXEk6.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/12/toggle-between-tabs-spaces-with-ease/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/12/toggle-between-tabs-spaces-with-ease/</feedburner:origLink></item>
		<item>
		<title>Creating Patches for Subversion from Git</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/198415026/</link>
		<comments>http://abombss.com/blog/2007/12/10/creating-patches-for-subversion-from-git/#comments</comments>
		<pubDate>Tue, 11 Dec 2007 04:29:26 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[git]]></category>

		<category><![CDATA[svn]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/10/creating-patches-for-subversion-from-git/</guid>
		<description><![CDATA[What a dreadful way to spend the last hour I wish it upon no one else.  I recently started using Git and git-svn to track some of my projects and I almost completely abandoned it because creating an svn friendly patch that something like TortoiseMerge could apply is impossible.  Then I found the [...]]]></description>
			<content:encoded><![CDATA[<p>What a dreadful way to spend the last hour I wish it upon no one else.  I recently started using <a href="http://git.or.cz/" onclick="javascript:pageTracker._trackPageview('/outbound/article/git.or.cz');" title="Git - Fast Version Control System" target="_blank">Git</a> and git-svn to track some of my projects and I almost completely abandoned it because creating an <a href="http://subversion.tigris.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/subversion.tigris.org');" target="_blank">svn</a> friendly patch that something like <a href="http://tortoisesvn.tigris.org/TortoiseMerge.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/tortoisesvn.tigris.org');" target="_blank">TortoiseMerge</a> could apply is impossible.  Then I found the <a href="http://code.google.com/p/git-svn-utils/" onclick="javascript:pageTracker._trackPageview('/outbound/article/code.google.com');" target="_blank">git-svn-utils</a> project.  It doesn&#8217;t look like its active but it does have a script <a href="http://git-svn-utils.googlecode.com/svn/trunk/git-svn-diff" onclick="javascript:pageTracker._trackPageview('/outbound/article/git-svn-utils.googlecode.com');" target="_blank">git-svn-diff</a> which is exactly what I was looking for.  Unfortunately the script was not handling new files the way subversion, or maybe <a href="http://tortoisesvn.tigris.org/TortoiseMerge.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/tortoisesvn.tigris.org');" target="_blank">TortoiseMerge</a> wanted.  So I made some pretty bad hacks <a href="http://abombss.com/wordpress/wp-content/uploads/2007/12/git-svn-diff.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wordpress/wp-content/uploads/2007/12/git-svn-diff.zip');" target="_blank">and came up with this version</a>.  It will create a full patch file that can be applied with <a href="http://tortoisesvn.tigris.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/tortoisesvn.tigris.org');" title="Tortoise SVN" target="_blank">TSVN</a>.</p>
<p>I am interested to know if I am the only one out there that had this problem or if there is a better solution.  Please let me know as I am a total git newb.</p>
<p><a href="http://abombss.com/wordpress/wp-content/uploads/2007/12/git-svn-diff.zip" onclick="javascript:pageTracker._trackPageview('/downloads/wordpress/wp-content/uploads/2007/12/git-svn-diff.zip');" title="Download git-svn-diff">Download git-svn-diff</a></p>
<p class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:65fd5283-2161-43b4-8aba-bb0eaed3e1ae" style="margin: 0px; padding: 0px; display: inline">[tag]git, svn[/tag]</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=jMdj1w.p"><img src="http://feeds.feedburner.com/~f/abombss?i=jMdj1w.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=BdsU46.P"><img src="http://feeds.feedburner.com/~f/abombss?i=BdsU46.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=InIAQ7.p"><img src="http://feeds.feedburner.com/~f/abombss?i=InIAQ7.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=quFZaG.P"><img src="http://feeds.feedburner.com/~f/abombss?i=quFZaG.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/10/creating-patches-for-subversion-from-git/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/10/creating-patches-for-subversion-from-git/</feedburner:origLink></item>
		<item>
		<title>MS MVC: Testing Routes</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/198030717/</link>
		<comments>http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 12:27:12 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/</guid>
		<description><![CDATA[In Scott&#8217;s post about routing he showed how you can easily test routes.  One cool thing about 3.5 asp.net extension framework is the introduction of new interfaces for IHttpContext, IHttpRequest, IHttpResponse, and some other.  This makes testing with mocks so much easier.  Here I will show you some tests I wrote to [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">Scott&#8217;s post about routing</a> he showed how you can easily test routes.  One cool thing about 3.5 asp.net extension framework is the introduction of new interfaces for IHttpContext, IHttpRequest, IHttpResponse, and some other.  This makes testing with <a href="http://www.ayende.com/projects/rhino-mocks.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ayende.com');" title="Rhino.Mocks" target="_blank">mocks</a> so much easier.  Here I will show you some tests I wrote to validate the routing rules we created for <a href="http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/"  target="_blank">simply restful routing</a> in the ms mvc framework.</p>
<h2>What Are We Testing?</h2>
<p>When testing we want to stick with one assertion per test.  So for this example we are only testing that the rules we wrote set the proper action.  <a href="http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/"  target="_blank">You can view the rules we will be testing in my previous post</a>.</p>
<h3>Create The Test Fixture</h3>
<pre><span style="color: #0000ff">using</span> System.Collections.Specialized;
<span style="color: #0000ff">using</span> System.Web;
<span style="color: #0000ff">using</span> System.Web.Mvc;
<span style="color: #0000ff">using</span> MVCContrib.SimplyRestful;
<span style="color: #0000ff">using</span> NUnit.Framework;
<span style="color: #0000ff">using</span> NUnit.Framework.SyntaxHelpers;
<span style="color: #0000ff">using</span> Rhino.Mocks;

<span style="color: #0000ff">namespace</span> MVCContrib.Specs.SimplyRestfulSpecs
{
  [TestFixture]
  <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> SimplyRestfulRouteMatchTests
  {
  }
}</pre>
<h3>Add The First Test</h3>
<pre>    [Test]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> GetRouteData_WithAControllerAndIdUsingAHttpGetRequest_SetsTheShowAction()
    {
    }</pre>
<p>Our test name is using pattern Method_Context_Result.  So the method under test is GetRouteData.  The context of the test is With a controller and id using a an http get request sets the show action.  Now lets fill in the test.</p>
<pre>    [Test]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> GetRouteData_WithAControllerAndIdUsingAHttpGetRequest_SetsTheShowAction()
    {
      IHttpContext httpContext;
      RouteCollection routeCollection = <span style="color: #0000ff">new</span> RouteCollection();
      SimplyRestfulRouteHandler.InitializeRoutes(routeCollection);
      RouteData routeData = routeCollection.GetRouteData(httpContext);
      Assert.That(routeData.Values["<span style="color: #8b0000">action</span>"], Is.EqualTo("<span style="color: #8b0000">show</span>").IgnoreCase);
    }</pre>
<p>Above we wrote our assertion.  We want to call the GetRouteData method on a routeCollection and we want to assert that the parameter named &#8220;action&#8221; is equal to show.  At this point the test will fail with a nre on httpContext.  httpContext needs to be an instance of IHttpContext, so how do we get an instance of an interface.  Simple, we mock it.  We will setup the mock context with just enough information for the RouteCollection to do its job.  This could be considered a stub and not a mock since we are simply using Rhino.Mocks to setup results.</p>
<pre>    [Test]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> GetRouteData_WithAControllerAndIdUsingAHttpGetRequest_SetsTheShowAction()
    {
      MockRepository mocks = <span style="color: #0000ff">new</span> MockRepository();
      IHttpContext httpContext = mocks.DynamicMock&lt;IHttpContext&gt;();
      IHttpRequest httpRequest = mocks.DynamicMock&lt;IHttpRequest&gt;();

      RouteCollection routeCollection = <span style="color: #0000ff">new</span> RouteCollection();
      SimplyRestfulRouteHandler.InitializeRoutes(routeCollection);

      <span style="color: #0000ff">using</span>(mocks.Record())
      {
        SetupResult.For(httpContext.Request)
          .Return(httpRequest);
        SetupResult.For(httpRequest.AppRelativeCurrentExecutionFilePath)
          .Return("<span style="color: #8b0000">~/products/123</span>");
        SetupResult.For(httpRequest.HttpMethod)
          .Return("<span style="color: #8b0000">GET</span>");
      }
      <span style="color: #0000ff">using</span>(mocks.Playback())
      {
        RouteData routeData = routeCollection.GetRouteData(httpContext);
        Assert.That(routeData.Values["<span style="color: #8b0000">action</span>"], Is.EqualTo("<span style="color: #8b0000">show</span>").IgnoreCase);
      }
    }</pre>
<p>So what just happened? First we created a MockRepository which is the core engine of Rhino.Mocks.  This could probably get moved to a [SetUp] method.  Next we create two Dynamic Mocks.  One for the context and one for the request.  We make them dynamic mocks because they are not under test.  We do not care what gets called on these interfaces or how it gets called.  We just care that if certain properties are called they return a specific values emulating what a real http request would look like.  Next we have the mocks.Record phase.  This is used to demarcate expectations versus assertions.</p>
<p>What to note is that the RouteCollection uses the AppRelativeCurrentExecutionFilePath property which expects a return string like &#8220;~/something/something/something.aspx&#8221; we are telling it to return &#8220;~/products/123&#8243; products is our controller and 123 should be our id of the route.  Next we setup a result for the Httpmethod property, remember our Route had validation on the special name Method which maps to a call on HttpMethod.</p>
<p>Finally we run our test and make the assertions.  We enter playback mode, execute the GetRouteData method, which is our method under test, pass in the mocked context and assert that the returned routedata has a parameter named &#8220;action&#8221; = &#8220;show&#8221;</p>
<p>So once you add a couple more tests for different routes you will see a way to factor some common code out.  I created a helper method to setup my context.</p>
<pre>    <span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> SetupContext(<span style="color: #0000ff">string</span> url, <span style="color: #0000ff">string</span> httpMethod, <span style="color: #0000ff">string</span> formMethod)
    {
      SetupResult.For(httpContext.Request).Return(httpRequest);
      SetupResult.For(httpRequest.AppRelativeCurrentExecutionFilePath).Return(url);
      SetupResult.For(httpRequest.HttpMethod).Return(httpMethod);
      <span style="color: #0000ff">if</span>(!<span style="color: #0000ff">string</span>.IsNullOrEmpty(formMethod))
      {
        NameValueCollection form = <span style="color: #0000ff">new</span> NameValueCollection();
        form.Add("<span style="color: #8b0000">_method</span>", formMethod);
        SetupResult.For(httpRequest.Form).Return(form);
      }
    }</pre>
<p>Then my tests simply look like this.</p>
<pre>    [Test]
    <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> GetRouteData_WithAControllerAndIdUsingFormMethodPut_UsesSimplyRestfulRouteHandler()
    {
      <span style="color: #0000ff">using</span> (mocks.Record())
      {
        SetupContext("<span style="color: #8b0000">~/controller/123</span>", "<span style="color: #8b0000">POST</span>", "<span style="color: #8b0000">PUT</span>");
      }
      <span style="color: #0000ff">using</span> (mocks.Playback())
      {
        RouteData routeData = routeCollection.GetRouteData(httpContext);
        Assert.That(routeData.Route.RouteHandler, Is.EqualTo(<span style="color: #0000ff">typeof</span>(SimplyRestfulRouteHandler)));
      }
    }</pre>
<p>The best part about writing tests for this stuff is you no longer have to fire up a browser and test by hand.  You get instant verification that runs quick.</p>
<p>If you are wondering how I figured out what to mock and setup results for it was a quick perusal of System.Web.Extensions in reflector.  Having to open reflector to figure out what to mock is a code smell for me.  You really shouldn&#8217;t be mocking things you don&#8217;t own or control but this is a nice quick integration test that can save you tons of time down the road.  Just don&#8217;t be surprised if after an update you get some errors because MS changed the implementation of RouteCollection.GetRouteData, another great reason for using a ContextSetup method.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=FTpuXb.p"><img src="http://feeds.feedburner.com/~f/abombss?i=FTpuXb.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=L26HlA.P"><img src="http://feeds.feedburner.com/~f/abombss?i=L26HlA.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=phdILN.p"><img src="http://feeds.feedburner.com/~f/abombss?i=phdILN.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=aAOk1W.P"><img src="http://feeds.feedburner.com/~f/abombss?i=aAOk1W.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/10/ms-mvc-testing-routes/</feedburner:origLink></item>
		<item>
		<title>MS MVC: Simply Restful Routing</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/197972483/</link>
		<comments>http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 10:05:36 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[aspnetmvc]]></category>

		<category><![CDATA[rest]]></category>

		<category><![CDATA[routing]]></category>

		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/</guid>
		<description><![CDATA[MS MVC first public code drop is available.  I hope you have read through all of ScottGu&#8217;s posts to help prep you for the drop.  If you haven&#8217;t I highly suggest reading about Routing first before you dive into this.
What we are going to do is build a Simply Restful Route Handler similar [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://weblogs.asp.net/scottgu/archive/2007/12/09/asp-net-3-5-extensions-ctp-preview-released.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">MS MVC first public code drop is available</a>.  I hope you have read through all of <a href="http://weblogs.asp.net/scottgu/default.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" target="_blank">ScottGu&#8217;s</a> posts to help prep you for the drop.  <a href="http://weblogs.asp.net/scottgu/archive/2007/12/03/asp-net-mvc-framework-part-2-url-routing.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/weblogs.asp.net');" title="ASP.NET MVC Framework (Part 2): URL Routing" target="_blank">If you haven&#8217;t I highly suggest reading about Routing first before you dive into this</a>.</p>
<p>What we are going to do is build a Simply Restful Route Handler similar to what is available in rails.  MS MVC supports restful routing pretty good out of the box.  The only case it doesn&#8217;t pick up is when browsers cannot send real HTTP PUT and DELETE requests.  To get around this we are going to build a very simple route handler to inspect a hidden field on the submitted form to set the intended action of the request.</p>
<p>We will be creating 8 restful routes, contrary to the 7 routes in simply restful.</p>
<h3></h3>
<h2>The Eight Actions</h2>
<ul>
<li>Show : handles a GET request for a displaying a single resource that the controller is representing.</li>
<li>Create : handles a POST request for a creating a new resource.</li>
<li>Update : handles a PUT request for updating an existing resource.</li>
<li>Destroy : handles a DELETE request on a resource.</li>
<li>Index : handles a GET request for a collection of resources.</li>
<li>New : handles a GET request for a blank form for creating a new resource</li>
<li>Edit : handles a GET request for a form with values filled in from the resource for updating.</li>
<li>Delete : handles a GET request a confirmation / form with options for deleting a resource. * This is the extra action.</li>
</ul>
<h2>The Routes</h2>
<table border="0" cellpadding="2" cellspacing="0" width="465">
<tr>
<td valign="top" width="91"><strong>Action</strong></td>
<td valign="top" width="172"><strong>Url</strong></td>
<td valign="top" width="106"><strong>Http Method</strong></td>
<td valign="top" width="94"><strong>Form Method</strong></td>
</tr>
<tr>
<td valign="top" width="92">Show</td>
<td valign="top" width="172">[controller]/[id]</td>
<td valign="top" width="106">GET</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Create</td>
<td valign="top" width="172">[controller]</td>
<td valign="top" width="106">POST</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Update</td>
<td valign="top" width="172">[controller]/[id]</td>
<td valign="top" width="106">PUT</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Update</td>
<td valign="top" width="172">[controller]/[id]</td>
<td valign="top" width="106">POST</td>
<td valign="top" width="94">PUT</td>
</tr>
<tr>
<td valign="top" width="92">Destroy</td>
<td valign="top" width="172">[controller]/[id]</td>
<td valign="top" width="106">DELETE</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Destroy</td>
<td valign="top" width="172">[controller]/[id]</td>
<td valign="top" width="106">POST</td>
<td valign="top" width="94">DELETE</td>
</tr>
<tr>
<td valign="top" width="92">Index</td>
<td valign="top" width="172">[controller]</td>
<td valign="top" width="106">GET</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">New</td>
<td valign="top" width="172">[controller]/new</td>
<td valign="top" width="106">GET</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Edit</td>
<td valign="top" width="172">[controller]/[id]/edit</td>
<td valign="top" width="106">GET</td>
<td valign="top" width="94"></td>
</tr>
<tr>
<td valign="top" width="92">Delete</td>
<td valign="top" width="172">[controller]/[id]/delete</td>
<td valign="top" width="106">GET</td>
<td valign="top" width="94"></td>
</tr>
</table>
<h3></h3>
<h2>The Simply Restful Routes In MS MVC</h2>
<pre>routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/new</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">new</span>" },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});
routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/[id]/[action]</span>",
  Validation = <span style="color: #0000ff">new</span>
  {
    Method = "<span style="color: #8b0000">GET</span>",
    Id = idValidationRegex ?? MatchAny,
    Action = "<span style="color: #8b0000">[eE][dD][iI][tT]|[dD][eE][lL][eE][tT][eE]</span>"
  },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/[id]</span>",
  Validation = <span style="color: #0000ff">new</span>
  {
    Method = "<span style="color: #8b0000">POST</span>",
    Id = idValidationRegex ?? MatchAny,
  },
  RouteHandler = <span style="color: #0000ff">typeof</span>(SimplyRestfulRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/[id]</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">show</span>" },
  Validation = <span style="color: #0000ff">new</span>
  {
    Method = "<span style="color: #8b0000">GET</span>",
    Id = idValidationRegex ?? MatchAny,
  },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/[id]</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">update</span>" },
  Validation = <span style="color: #0000ff">new</span>
  {
    Method = "<span style="color: #8b0000">PUT</span>",
    Id = idValidationRegex ?? MatchAny
  },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]/[id]</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">destroy</span>" },
  Validation = <span style="color: #0000ff">new</span>
  {
    Method = "<span style="color: #8b0000">DELETE</span>",
    Id = idValidationRegex ?? MatchAny
  },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">index</span>" },
  Validation = <span style="color: #0000ff">new</span> { Method = "<span style="color: #8b0000">GET</span>" },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});

routeCollection.Add(<span style="color: #0000ff">new</span> Route
{
  Url = "<span style="color: #8b0000">[controller]</span>",
  Defaults = <span style="color: #0000ff">new</span> { Action = "<span style="color: #8b0000">create</span>" },
  Validation = <span style="color: #0000ff">new</span> { Method = "<span style="color: #8b0000">POST</span>" },
  RouteHandler = <span style="color: #0000ff">typeof</span>(MvcRouteHandler)
});</pre>
<p>I am not going to explain much of what is going on above, have a look at ScottGu&#8217;s post on routing for that.  What I will point out are a couple things.  First we use use some hard matches like [controller]/new and map that with a Default action.  Very straightforward but just a good example of how Routes and Defaults work.  Second we add some validation.  Scott covered the standard validation that accepts a regex.  You will notice that the regex is case sensitive so we end up with a pretty wacky looking string for &#8220;Edit|Delete&#8221;.  Third, we are using a special validation property named Method which will match on the HttpMethod of the Request.  And finally notice we only have a single rule that will require a custom IRouteHandler.</p>
<p>So lets start with a story for our new custom route handler:</p>
<blockquote><p><em>Story:</em> RouteHandler Assigns Restful Actions</p>
<p><em>As</em> a Route Handler<br />
<em>I</em> want standard post requests to route to restful actions.<br />
<em>So</em> that people without javascript enabled or incompatible browsers can still have a restful experience and my web server needs to issue less browser redirects.</p>
<p>Acceptance Criteria:</p>
<p><em>Scenario 1:</em> Form _method PUT Triggers Update Action<br />
<em>GIVEN</em> the form has a field named _method with a value of PUT<br />
<em>AND</em> the url matches [controller]/[id]<br />
<em>AND </em>the HTTP method is POST<br />
<em>WHEN</em> the form is posted<br />
<em>THEN</em> the route action should be Update</p>
<p><em>Scenario 2:</em> DELETE Triggers Destroy Action<br />
<em>GIVEN</em> the form has a field named _method with a value of DELETE<br />
<em>AND</em> the url matches [controller]/[id]<br />
<em>AND</em> the HTTP method is POST<br />
<em>WHEN</em> the form is posted<br />
<em>THEN</em> the route action should be Delete</p></blockquote>
<h2>TDD First</h2>
<p>To make testing easier I will be using Rhino.Mocks to create dynamic mocks of the IHttpContext and IHttpRequest.  Thanks Microsoft for finally giving us interfaces to make our testing easier.</p>
<pre>[TestFixture]
[Category("<span style="color: #8b0000">SimplyRestfulSpecs</span>")]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> When_The_Form_Is_Posted_With_A_Form_Field_Named_Method_And_A_Value_Of_PUT
: BaseRouteHandlerTestFixture
{
[SetUp]
<span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> GivenSetupContext()
{
  <span style="color: #0000ff">base</span>.GivenSetupContext();
  form.Add("<span style="color: #8b0000">_method</span>", "<span style="color: #8b0000">PUT</span>");
}

[Test]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Then_The_Route_Action_Should_Be_Set_To_Update()
{
  RestfulAction action = RestfulAction.None;
  IRestfulActionResolver resolver = <span style="color: #0000ff">new</span> RestfulActionResolver();

  <span style="color: #0000ff">using</span>(mocks.Record())
  {
    SetupResult.For(httpContext.Request).Return(httpRequest);
    SetupResult.For(httpRequest.RequestType).Return("<span style="color: #8b0000">POST</span>");
    SetupResult.For(httpRequest.Form).Return(form);
    requestContext = <span style="color: #0000ff">new</span> RequestContext(httpContext, routeData);
  }

  <span style="color: #0000ff">using</span>(mocks.Playback())
  {
    action = resolver.ResolveAction(requestContext);
    Assert.That(action, Is.EqualTo(RestfulAction.Update));
  }
}
}

[TestFixture]
[Category("<span style="color: #8b0000">SimplyRestfulSpecs</span>")]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> When_The_Form_Is_Posted_With_A_Form_Field_Named_Method_And_A_Value_Of_DELETE
: BaseRouteHandlerTestFixture
{
[SetUp]
<span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> GivenSetupContext()
{
  <span style="color: #0000ff">base</span>.GivenSetupContext();
  form.Add("<span style="color: #8b0000">_method</span>", "<span style="color: #8b0000">DELETE</span>");
}

[Test]
<span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Then_The_Route_Action_Should_Be_Set_To_Destroy()
{
  RestfulAction action = RestfulAction.None;
  IRestfulActionResolver resolver = <span style="color: #0000ff">new</span> RestfulActionResolver();

  <span style="color: #0000ff">using</span> (mocks.Record())
  {
    SetupResult.For(httpContext.Request).Return(httpRequest);
    SetupResult.For(httpRequest.RequestType).Return("<span style="color: #8b0000">POST</span>");
    SetupResult.For(httpRequest.Form).Return(form);
    requestContext = <span style="color: #0000ff">new</span> RequestContext(httpContext, routeData);
  }

  <span style="color: #0000ff">using</span> (mocks.Playback())
  {
    action = resolver.ResolveAction(requestContext);
    Assert.That(action, Is.EqualTo(RestfulAction.Destroy));
  }
}
}</pre>
<pre>  #region BaseRouteHandlerTestFixture
  <span style="color: #0000ff">public</span> <span style="color: #0000ff">abstract</span> <span style="color: #0000ff">class</span> BaseRouteHandlerTestFixture
  {
    <span style="color: #0000ff">protected</span> MockRepository mocks;
    <span style="color: #0000ff">protected</span> IHttpContext httpContext;
    <span style="color: #0000ff">protected</span> IHttpRequest httpRequest;
    <span style="color: #0000ff">protected</span> RouteData routeData;
    <span style="color: #0000ff">protected</span> RequestContext requestContext;
    <span style="color: #0000ff">protected</span> NameValueCollection form;

    <span style="color: #0000ff">protected</span> <span style="color: #0000ff">virtual</span> <span style="color: #0000ff">void</span> GivenSetupContext()
    {
      mocks = <span style="color: #0000ff">new</span> MockRepository();
      httpContext = mocks.DynamicMock&lt;IHttpContext&gt;();
      httpRequest = mocks.DynamicMock&lt;IHttpRequest&gt;();

      routeData = <span style="color: #0000ff">new</span> RouteData();
      routeData.Values.Add("<span style="color: #8b0000">controller</span>", "<span style="color: #8b0000">testcontroller</span>");
      routeData.Values.Add("<span style="color: #8b0000">action</span>", "<span style="color: #8b0000">update</span>");

      form = <span style="color: #0000ff">new</span> NameValueCollection();
    }
  }
  #endregion</pre>
<h2>The Code</h2>
<p><span style="color: #0000ff">public</span> <span style="color: #0000ff">enum</span> RestfulAction<br />
{<br />
None = 16384,<br />
Show = 1,<br />
Create = 2,<br />
Update = 4,<br />
Destroy = 8,<br />
Index = 16,<br />
New = 32,<br />
Edit = 64,<br />
Delete = 128<br />
}</p>
<p><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> SimplyRestfulRouteHandler : MvcRouteHandler<br />
{<br />
<span style="color: #0000ff">private</span> <span style="color: #0000ff">const</span> <span style="color: #0000ff">string</span> MatchAny = &#8220;<span style="color: #8b0000">*</span>&#8220;;</p>
<p><span style="color: #0000ff">private</span> IRestfulActionResolver actionResolver;</p>
<p><span style="color: #0000ff">public</span> SimplyRestfulRouteHandler()<br />
{<br />
actionResolver = <span style="color: #0000ff">new</span> RestfulActionResolver();<br />
}</p>
<p><span style="color: #0000ff">public</span> SimplyRestfulRouteHandler(IRestfulActionResolver actionResolver)<br />
{<br />
<span style="color: #0000ff">this</span>.actionResolver = actionResolver;<br />
}</p>
<p><span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> IHttpHandler GetHttpHandler(RequestContext requestContext)<br />
{<br />
EnsureActionResolver(requestContext.HttpContext);</p>
<p>RestfulAction action = actionResolver.ResolveAction(requestContext);<br />
<span style="color: #0000ff">if</span> (action != RestfulAction.None)<br />
{<br />
requestContext.RouteData.Values["<span style="color: #8b0000">action</span>"] = action.ToString();<br />
}<br />
<span style="color: #0000ff">return</span> <span style="color: #0000ff">base</span>.GetHttpHandler(requestContext);<br />
}</p>
<p><span style="color: #0000ff">private</span> <span style="color: #0000ff">void</span> EnsureActionResolver(IServiceProvider serviceProvider)<br />
{<br />
<span style="color: #0000ff">if</span> (actionResolver == <span style="color: #0000ff">null</span>)<br />
{<br />
actionResolver = (IRestfulActionResolver)<br />
serviceProvider.GetService(<span style="color: #0000ff">typeof</span>(IRestfulActionResolver));<br />
<span style="color: #0000ff">if</span> (actionResolver == <span style="color: #0000ff">null</span>)<br />
actionResolver = <span style="color: #0000ff">new</span> RestfulActionResolver();<br />
}<br />
}<br />
}</p>
<p><span style="color: #0000ff">public</span> <span style="color: #0000ff">interface</span> IRestfulActionResolver<br />
{<br />
RestfulAction ResolveAction(RequestContext context);<br />
}</p>
<p><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> RestfulActionResolver : IRestfulActionResolver<br />
{<br />
<span style="color: #0000ff">public</span> RestfulAction ResolveAction(RequestContext context)<br />
{<br />
<span style="color: #0000ff">if</span> (context == <span style="color: #0000ff">null</span> ||<br />
context.HttpContext == <span style="color: #0000ff">null</span> ||<br />
context.HttpContext.Request == <span style="color: #0000ff">null</span>)<br />
{<br />
<span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> NullReferenceException(&#8221;<span style="color: #8b0000">Request in current HttpContext cannot be null.</span>&#8220;);<br />
}</p>
<p><span style="color: #0000ff">if</span> (<span style="color: #0000ff">string</span>.IsNullOrEmpty(context.HttpContext.Request.RequestType))<br />
{<br />
<span style="color: #0000ff">return</span> RestfulAction.None;<br />
}</p>
<p><span style="color: #0000ff">string</span> requestType = context.HttpContext.Request.RequestType.ToLowerInvariant();<br />
<span style="color: #0000ff">if</span> (<span style="color: #0000ff">string</span>.Equals(requestType, &#8220;<span style="color: #8b0000">post</span>&#8220;, StringComparison.Ordinal))<br />
{<br />
<span style="color: #0000ff">return</span> ResolvePostAction(context);<br />
}</p>
<p><span style="color: #0000ff">return</span> RestfulAction.None;<br />
}</p>
<p><span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> RestfulAction ResolvePostAction(RequestContext context)<br />
{<br />
<span style="color: #0000ff">if</span> (context.HttpContext.Request.Form == <span style="color: #0000ff">null</span>)<br />
{<br />
<span style="color: #0000ff">return</span> RestfulAction.None;<br />
}</p>
<p><span style="color: #0000ff">string</span> formMethod = context.HttpContext.Request.Form["<span style="color: #8b0000">_method</span>"];<br />
<span style="color: #0000ff">if</span> (<span style="color: #0000ff">string</span>.IsNullOrEmpty(formMethod))<br />
{<br />
<span style="color: #0000ff">return</span> RestfulAction.None;<br />
}</p>
<p>formMethod = formMethod.Trim();<br />
<span style="color: #0000ff">if</span> (<span style="color: #0000ff">string</span>.Equals(&#8221;<span style="color: #8b0000">put</span>&#8220;, formMethod, StringComparison.OrdinalIgnoreCase))<br />
{<br />
<span style="color: #0000ff">return</span> RestfulAction.Update;<br />
}<br />
<span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span>(<span style="color: #0000ff">string</span>.Equals(&#8221;<span style="color: #8b0000">delete</span>&#8220;, formMethod, StringComparison.OrdinalIgnoreCase))<br />
{<br />
<span style="color: #0000ff">return</span> RestfulAction.Destroy;<br />
}</p>
<p><span style="color: #0000ff">return</span> RestfulAction.None;<br />
}<br />
}</p>
<h2>Conclusion</h2>
<p>The only opinion I have so far on MS-MVC is it beats the heck out of WebForms and I am glad to see MS is committed to supporting a product that fits this space.  In the coming weeks I should have much more about the framework.  I just wanted to get something usable out to the community first.</p>
<p><a href="http://mvccontrib.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/mvccontrib.org');" target="_blank">I hope to get this stuff into the new MVC Contrib project as well.</a></p>
<p>Whats next, maybe some form helpers, templates, and a base controller to make working with the views and actions a little easier.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=LzDUiq.p"><img src="http://feeds.feedburner.com/~f/abombss?i=LzDUiq.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=whmaVb.P"><img src="http://feeds.feedburner.com/~f/abombss?i=whmaVb.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=qglSm0.p"><img src="http://feeds.feedburner.com/~f/abombss?i=qglSm0.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=Op0JiT.P"><img src="http://feeds.feedburner.com/~f/abombss?i=Op0JiT.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/12/10/ms-mvc-simply-restful-routing/</feedburner:origLink></item>
		<item>
		<title>MS and Adobe are Fighting…</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/178362184/</link>
		<comments>http://abombss.com/blog/2007/11/01/ms-and-adobe-are-fighting/#comments</comments>
		<pubDate>Thu, 01 Nov 2007 19:12:29 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Technology]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[adobe]]></category>

		<category><![CDATA[microsoft]]></category>

		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/11/01/ms-and-adobe-are-fighting/</guid>
		<description><![CDATA[Seriously&#8230; I am getting fed up with the stability of my workstation lately.  Its vista ultimate x64.  I don&#8217;t know if its vista or x64, or even worse the combination of the two.
Since when did VS2k5 have a dependency on Adobe Flash?

I guess VS didn&#8217;t see this..

This tiny annoyance is only a single [...]]]></description>
			<content:encoded><![CDATA[<p>Seriously&#8230; I am getting fed up with the stability of my workstation lately.  Its vista ultimate x64.  I don&#8217;t know if its vista or x64, or even worse the combination of the two.</p>
<p>Since when did VS2k5 have a dependency on Adobe Flash?</p>
<p><a href="http://abombss.com/wordpress/wp-content/uploads/2007/11/vs-sucks-01.jpg"  atomicselection="true"><img src="http://abombss.com/wordpress/wp-content/uploads/2007/11/vs-sucks-01-thumb.jpg" style="border: 0px none " alt="vs-sucks-01" border="0" height="189" width="385" /></a></p>
<p>I guess VS didn&#8217;t see this..</p>
<p><a href="http://abombss.com/wordpress/wp-content/uploads/2007/11/vs-sucks-01-i-have-flash.jpg"  atomicselection="true"><img src="http://abombss.com/wordpress/wp-content/uploads/2007/11/vs-sucks-01-i-have-flash-thumb.jpg" style="border: 0px none " alt="vs-sucks-01-i-have-flash" border="0" height="379" width="251" /></a></p>
<p>This tiny annoyance is only a single piece of the instability I am seeing all over my system.</p>
<p>This could go on for a long time so I will just stop here.</p>
<p>Oh&#8230; BTW Windows Live Writer stopped working after I published this post.  Its part of the new MRPP.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=fvmfR3.p"><img src="http://feeds.feedburner.com/~f/abombss?i=fvmfR3.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=RrKKv4.P"><img src="http://feeds.feedburner.com/~f/abombss?i=RrKKv4.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=yxPHgS.p"><img src="http://feeds.feedburner.com/~f/abombss?i=yxPHgS.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=pxl4H0.P"><img src="http://feeds.feedburner.com/~f/abombss?i=pxl4H0.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/11/01/ms-and-adobe-are-fighting/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/11/01/ms-and-adobe-are-fighting/</feedburner:origLink></item>
		<item>
		<title>Whose Home is Chicago: Clinton’s or Obama’s?</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/170458513/</link>
		<comments>http://abombss.com/blog/2007/10/15/whose-home-is-chicago-clintons-or-obamas/#comments</comments>
		<pubDate>Tue, 16 Oct 2007 02:41:23 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Life]]></category>

		<category><![CDATA[politics]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/10/15/whose-home-is-chicago-clintons-or-obamas/</guid>
		<description><![CDATA[Congratulations to Thom Serafin for his 5 seconds of fame (1:07-1:12) on the Today Show this morning. Thom has been mentor of mine and I have had the privilege of working with him and coaching youth football with him.
Congrats Thom!
Clinton or Obama? No comment&#8230;
]]></description>
			<content:encoded><![CDATA[<p><a href="http://video.msn.com/video.aspx?mkt=en-US&amp;brand=msnbc&amp;vid=61c5b0f3-9511-4d5c-ac7b-fe2836550fd6" onclick="javascript:pageTracker._trackPageview('/outbound/article/video.msn.com');" title="True Chicagoan: Clinton or Obama?" target="_new"><img src="http://msnbcmedia.msn.com/j//msnbc/Components/Video/071015/tdy_lauer_chicagopoliticians_071015.vmodv4.jpg" style="margin: 0px 10px 0px 0px" alt="True Chicagoan: Clinton or Obama?" align="left" height="84" width="112" /></a>Congratulations to <a href="http://www.serafin.com/about.php" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.serafin.com');" title="Thom Serafin of Serafin &amp; Associates">Thom Serafin</a> for his 5 seconds of fame <a href="http://video.msn.com/video.aspx?mkt=en-US&amp;brand=msnbc&amp;vid=61c5b0f3-9511-4d5c-ac7b-fe2836550fd6" onclick="javascript:pageTracker._trackPageview('/outbound/article/video.msn.com');" title="Video of Thom Serafin on the Today Show" target="_blank"><span style="font-size: smaller">(1:07-1:12)</span></a> on the <a href="http://www.msnbc.msn.com/id/3032633/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.msnbc.msn.com');" title="The Today Show" target="_blank">Today Show</a> this morning. Thom has been mentor of mine and I have had the privilege of working with him and coaching youth football with him.</p>
<p><strong>Congrats Thom!</strong></p>
<p><em>Clinton or Obama?</em> <strong>No comment&#8230;</strong></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=vKsr9l.p"><img src="http://feeds.feedburner.com/~f/abombss?i=vKsr9l.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=4b8RQN.P"><img src="http://feeds.feedburner.com/~f/abombss?i=4b8RQN.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=mB7BFz.p"><img src="http://feeds.feedburner.com/~f/abombss?i=mB7BFz.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=aXQSXE.P"><img src="http://feeds.feedburner.com/~f/abombss?i=aXQSXE.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/10/15/whose-home-is-chicago-clintons-or-obamas/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/10/15/whose-home-is-chicago-clintons-or-obamas/</feedburner:origLink></item>
		<item>
		<title>How to Speed Up Build Times With NHQG and MSBuild</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/169258390/</link>
		<comments>http://abombss.com/blog/2007/10/12/how-to-speed-up-build-times-with-nhqg-and-msbuild/#comments</comments>
		<pubDate>Sat, 13 Oct 2007 00:42:34 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[msbuild]]></category>

		<category><![CDATA[nhibernate]]></category>

		<category><![CDATA[nhqg]]></category>

		<category><![CDATA[rhino]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/10/12/how-to-speed-up-build-times-with-nhqg-and-msbuild/</guid>
		<description><![CDATA[I love Ayende&#8217;s Rhino projects, especially his NHibernate Query Generator (NHQG). Since on most of my active development I am use NHibernate, Castle, and Rhino.Commons trunks, I keep nhqg in a tools directory and I was using a PreBuild command to generate the query builders. This had the negative impact of always rebuilding my domain [...]]]></description>
			<content:encoded><![CDATA[<p>I love <a href="http://www.ayende.com/blog" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.ayende.com');" target="_blank">Ayende&#8217;s</a> <a href="http://sourceforge.net/projects/rhino-tools/" onclick="javascript:pageTracker._trackPageview('/outbound/article/sourceforge.net');" title="Rhino Tools on SourceForge" target="_blank">Rhino projects</a>, especially his NHibernate Query Generator (NHQG). Since on most of my active development I am use NHibernate, Castle, and <a href="http://ayende.com/wiki/Rhino+Commons.ashx" onclick="javascript:pageTracker._trackPageview('/outbound/article/ayende.com');" title="Rhino.Commons WIki Page" target="_blank">Rhino.Commons</a> trunks, I keep nhqg in a tools directory and I was using a PreBuild command to generate the query builders. This had the negative impact of always rebuilding my domain project, even if a change was only made in another project. So, here is an msbuild snippet to generate my query builders only when my NHibernate mapping files change.</p>
<pre><span style="color: #0000ff">&lt;</span><span style="color: #800000">ItemGroup</span><span style="color: #0000ff">&gt;</span>
 <span style="color: #0000ff">&lt;</span><span style="color: #800000">NH</span>-<span style="color: #ff0000">Mappings</span> <span style="color: #ff0000">Include</span>=<span style="color: #0000ff">"DomainQuery***.hbm.xml"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">ItemGroup</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">Target</span> <span style="color: #ff0000">Name</span>=<span style="color: #0000ff">"BeforeBuild"</span>
 <span style="color: #ff0000">Inputs</span>=<span style="color: #0000ff">"@(NH-Mappings)"</span>
 <span style="color: #ff0000">Outputs</span>=<span style="color: #0000ff">"@(NH-Mappings -&gt; '%(RelativeDir)Generated%(Filename).cs')"</span><span style="color: #0000ff">&gt;</span>
  <span style="color: #0000ff">&lt;</span><span style="color: #800000">Exec</span> <span style="color: #ff0000">Command</span>=<span style="color: #0000ff">"$(SolutionDir)..toolsnhqgNHQG.exe /lang:cs /files:%22$(ProjectDir)DomainQuery*.hbm.xml%22 /out:%22$(ProjectDir)DomainQueryGenerated%22"</span> <span style="color: #0000ff">/&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">Target</span><span style="color: #0000ff">&gt;</span></pre>
<p>The Inputs and Ouputs of the Target is what allows <a href="http://blogs.msdn.com/msbuild/" onclick="javascript:pageTracker._trackPageview('/outbound/article/blogs.msdn.com');" title="MsBuild Team Blog" target="_blank">msbuild</a> to conditionally run the task. I use an <a href="http://msdn2.microsoft.com/en-us/library/ms171476.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/msdn2.microsoft.com');" title="MsBuild Transform Reference on MSDN" target="_blank">msbuild transform</a> to convert my mapping file name into the nhqg generated file name. Also, notice the %22 in command. This is the only way I could figure out how to pass quotes to a cmd inside of msbuild.</p>
<p>And the confirmation&#8230;</p>
<pre>
Target BeforeBuild:
  Skipping target "BeforeBuild" because all output files are up-to-date with respect to the input files.
  Input files: DomainQueryPost.hbm.xml;DomainQueryContributor.hbm.xml;DomainQueryTag.hbm.xml;DomainQueryItem.hbm.xml;DomainQueryBlog.hbm.xml;DomainQueryTagStat.hbm.xml
  Output files: DomainQueryGeneratedItem.hbm.cs;DomainQueryGeneratedTagStat.hbm.cs;DomainQueryGeneratedContributor.hbm.cs;DomainQueryGeneratedBlog.hbm.cs;DomainQueryGeneratedPost.hbm.cs;DomainQueryGeneratedTag.hbm.cs</pre>
<p>Happy Building <img src='http://abombss.com/wordpress/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:9912f839-6a89-49d8-a107-472b4db9983a" contenteditable="false" style="margin: 0px; padding: 0px; display: inline">[tag]nhibernate, rhino, nhqg, .net, msbuild[/tag]</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=FWcmY8.p"><img src="http://feeds.feedburner.com/~f/abombss?i=FWcmY8.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=s2b2xJ.P"><img src="http://feeds.feedburner.com/~f/abombss?i=s2b2xJ.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=pougkH.p"><img src="http://feeds.feedburner.com/~f/abombss?i=pougkH.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=DsfTY8.P"><img src="http://feeds.feedburner.com/~f/abombss?i=DsfTY8.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/10/12/how-to-speed-up-build-times-with-nhqg-and-msbuild/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/10/12/how-to-speed-up-build-times-with-nhqg-and-msbuild/</feedburner:origLink></item>
		<item>
		<title>How Do Your Projects Go?</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/169258391/</link>
		<comments>http://abombss.com/blog/2007/10/10/how-do-your-projects-go/#comments</comments>
		<pubDate>Wed, 10 Oct 2007 07:02:43 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[funny]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/10/10/how-do-your-projects-go/</guid>
		<description><![CDATA[
]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.linuxkungfu.org/images/fun/geek/project.jpg" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.linuxkungfu.org');"><img src="http://abombss.com/wordpress/wp-content/uploads/2007/10/project-thumb.jpg" title="project" style="border: 0px none " alt="project" border="0" height="180" width="240" /></a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=nRqcWA.p"><img src="http://feeds.feedburner.com/~f/abombss?i=nRqcWA.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=0SB9zC.P"><img src="http://feeds.feedburner.com/~f/abombss?i=0SB9zC.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=kQybzh.p"><img src="http://feeds.feedburner.com/~f/abombss?i=kQybzh.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=4i2k7n.P"><img src="http://feeds.feedburner.com/~f/abombss?i=4i2k7n.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/10/10/how-do-your-projects-go/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/10/10/how-do-your-projects-go/</feedburner:origLink></item>
		<item>
		<title>Local and UTC Dates in NHibernate</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/169258392/</link>
		<comments>http://abombss.com/blog/2007/10/09/local-and-utc-dates-in-nhibernate/#comments</comments>
		<pubDate>Wed, 10 Oct 2007 01:36:54 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[nhibernate]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/10/09/local-and-utc-dates-in-nhibernate/</guid>
		<description><![CDATA[How do you get a UTC datetime hydrated from NHibernate?  Dan Morphis addressed this a while ago with an interceptor.
I proposed a patch to NHibernate that adds UtcDateTime and LocalDateTime data types that will specifically get hydrated with the proper DateTimeKind value instead of DateTimeKind.Unspecified.

Usage
&#60;property name="MyDate" type="UtcDateTime"&#62;&#60;/property&#62;
&#60;property name="LocalDate" type="LocalDateTime"&#62;&#60;/property&#62;

You download the patch from Jira, [...]]]></description>
			<content:encoded><![CDATA[<p>How do you get a UTC datetime hydrated from NHibernate?  Dan Morphis addressed this a while ago with an <a href="http://www.milkcarton.com/blog/2007/01/19/NHibernate+DateTime+And+UTC.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.milkcarton.com');" target="_blank">interceptor</a>.</p>
<p>I <a href="http://jira.nhibernate.org/browse/NH-1135" onclick="javascript:pageTracker._trackPageview('/outbound/article/jira.nhibernate.org');" title="NH-1135" target="_blank">proposed a patch to NHibernate</a> that adds UtcDateTime and LocalDateTime data types that will specifically get hydrated with the proper DateTimeKind value instead of DateTimeKind.Unspecified.</p>
<pre>
Usage
&lt;property name="MyDate" type="UtcDateTime"&gt;&lt;/property&gt;
&lt;property name="LocalDate" type="LocalDateTime"&gt;&lt;/property&gt;
</pre>
<p>You download the patch from <a href="http://jira.nhibernate.org/secure/attachment/12188/NH-LocalAndUtcDateTimeType-02.patch" onclick="javascript:pageTracker._trackPageview('/outbound/article/jira.nhibernate.org');" title="NH Local And UTc DateTime Type Patch" target="_blank">Jira</a>, and vote for it if you like it.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=Ospd5c.p"><img src="http://feeds.feedburner.com/~f/abombss?i=Ospd5c.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=wsJxf6.P"><img src="http://feeds.feedburner.com/~f/abombss?i=wsJxf6.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=2GmBl6.p"><img src="http://feeds.feedburner.com/~f/abombss?i=2GmBl6.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=q7LHWP.P"><img src="http://feeds.feedburner.com/~f/abombss?i=q7LHWP.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/10/09/local-and-utc-dates-in-nhibernate/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/10/09/local-and-utc-dates-in-nhibernate/</feedburner:origLink></item>
		<item>
		<title>Alt.net IS NOT Devisive</title>
		<link>http://feeds.feedburner.com/~r/abombss/~3/169258393/</link>
		<comments>http://abombss.com/blog/2007/10/08/altnet-is-not-devisive/#comments</comments>
		<pubDate>Mon, 08 Oct 2007 17:20:11 +0000</pubDate>
		<dc:creator>Adam Tybor</dc:creator>
		
		<category><![CDATA[Development]]></category>

		<category><![CDATA[.net]]></category>

		<category><![CDATA[alt.net]]></category>

		<category><![CDATA[thoughts]]></category>

		<guid isPermaLink="false">http://abombss.com/blog/2007/10/08/altnet-is-not-devisive/</guid>
		<description><![CDATA[For those thinking that alt.net  is negative and is divisive I  remind of you David Laribee&#8217;s post several months ago about proposing the alt.net name.  Now how  can that mission be unclear, divisive, or negative?
If you have been doing agile, ddd, tdd, bdd, mvc, orm, ioc, di, and ci before alt.net, [...]]]></description>
			<content:encoded><![CDATA[<p>For those thinking that <a href="http://samgentile.com/blogs/samgentile/archive/2007/10/06/goodbye-codebetter-and-alt-net.aspx" onclick="javascript:pageTracker._trackPageview('/outbound/article/samgentile.com');" title="Sam Gentile's Blog">alt.net  is negative</a> and <a href="http://colinramsay.co.uk/2007/10/07/abandon-altnet/" onclick="javascript:pageTracker._trackPageview('/outbound/article/colinramsay.co.uk');" title="Colin Ramsay">is divisive</a> I  remind of you David Laribee&#8217;s post several months ago about proposing the <a href="http://laribee.com/blog/2007/04/10/altnet/" onclick="javascript:pageTracker._trackPageview('/outbound/article/laribee.com');" title="Alt.Net by David Laribee">alt.net name</a>.  Now how  can that mission be unclear, divisive, or negative?</p>
<p>If you have been doing <a href="http://en.wikipedia.org/wiki/Agile_software_development" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Agile Software Development">agile</a>, <a href="http://www.domaindrivendesign.org/" onclick="javascript:pageTracker._trackPageview('/outbound/article/www.domaindrivendesign.org');" title="Domain Driven Design">ddd</a>, <a href="http://en.wikipedia.org/wiki/Test-driven_development" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Test Driven Development">tdd</a>, <a href="http://en.wikipedia.org/wiki/Behavior_driven_development" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Behavior Driven Development">bdd</a>, <a href="http://en.wikipedia.org/wiki/Model-view-controller" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Model View Controller">mvc</a>, <a href="http://en.wikipedia.org/wiki/Object-relational_mapping" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Object Relational Mapping">orm</a>, <a href="http://en.wikipedia.org/wiki/Inversion_of_control" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Inversion of Control">ioc</a>, <a href="http://en.wikipedia.org/wiki/Dependency_injection" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Dependency Injection">di</a>, and <a href="http://en.wikipedia.org/wiki/Continuous_integration" onclick="javascript:pageTracker._trackPageview('/outbound/article/en.wikipedia.org');" title="Continuous Integration">ci </a>before alt.net, fantastic, so have most people in the software world. Alt.net is more than acronyms, practices, and tools.  Its a mindset.  Its trying help other .net community members think critically about their software and how their building it.</p>
<p>It is not about dictating policy, practice, or tooling.  It is not about alienating people or ideas.  It is about trying foster new growth within the .net community itself.</p>
<blockquote><p>We can never be sure that the opinion we are endeavoring to stifle is a false opinion; and if we were sure, stifling it would be an evil still.<br />
&#8211; John Stuart Mill</p></blockquote>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/abombss?a=zL2yyZ.p"><img src="http://feeds.feedburner.com/~f/abombss?i=zL2yyZ.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=GUzVL9.P"><img src="http://feeds.feedburner.com/~f/abombss?i=GUzVL9.P" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=9JNEJa.p"><img src="http://feeds.feedburner.com/~f/abombss?i=9JNEJa.p" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/abombss?a=TxJyEI.P"><img src="http://feeds.feedburner.com/~f/abombss?i=TxJyEI.P" border="0"></img></a>
</div>]]></content:encoded>
			<wfw:commentRss>http://abombss.com/blog/2007/10/08/altnet-is-not-devisive/feed/</wfw:commentRss>
		<feedburner:origLink>http://abombss.com/blog/2007/10/08/altnet-is-not-devisive/</feedburner:origLink></item>
	<feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=abombss</feedburner:awareness></channel>
</rss>
