<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns: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:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Pedro Reys</title>
	
	<link>http://blog.pedroreys.com</link>
	<description>Red, Green, Refactor!</description>
	<lastBuildDate>Fri, 30 Jul 2010 03:25:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/pedroreys" /><feedburner:info uri="pedroreys" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>HotFix for Checkdisk hanging at 1 sec</title>
		<link>http://feedproxy.google.com/~r/pedroreys/~3/F2L1eny8DAk/</link>
		<comments>http://blog.pedroreys.com/2010/07/30/hotfix-for-checkdisk-hanging-at-1-sec/#comments</comments>
		<pubDate>Fri, 30 Jul 2010 03:22:07 +0000</pubDate>
		<dc:creator>Pedro</dc:creator>
				<category><![CDATA[Tips]]></category>
		<category><![CDATA[CheckDisk]]></category>
		<category><![CDATA[HotFix]]></category>
		<category><![CDATA[KB]]></category>

		<guid isPermaLink="false">http://blog.pedroreys.com/2010/07/30/hotfix-for-checkdisk-hanging-at-1-sec/</guid>
		<description><![CDATA[I have a Dell Studio XPS 1640 running Windows 7 Home Premium x64. Yesterday it crashed (sigh) and when I rebooted the check disk was triggered. To my, not pleasant, surprise, Check Disk hanged at 1 sec left on the countdown for pressing a key to skip the disk check. Doing a hard reboot several [...]]]></description>
			<content:encoded><![CDATA[<p>I have a Dell Studio XPS 1640 running Windows 7 Home Premium x64. </p>
<p>Yesterday it crashed (sigh) and when I rebooted the check disk was triggered. To my, not pleasant, surprise, Check Disk hanged at 1 sec left on the countdown for pressing a key to skip the disk check. Doing a hard reboot several times I was able to start windows again.</p>
<p>Well, after some googling I found the <a href="http://support.microsoft.com/kb/975778">HOTFIX KB 975778</a> that solved the issue like a charm for me.</p>
<img src="http://feeds.feedburner.com/~r/pedroreys/~4/F2L1eny8DAk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.pedroreys.com/2010/07/30/hotfix-for-checkdisk-hanging-at-1-sec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.pedroreys.com/2010/07/30/hotfix-for-checkdisk-hanging-at-1-sec/</feedburner:origLink></item>
		<item>
		<title>Handling Content Type as we should, through HTTP Headers</title>
		<link>http://feedproxy.google.com/~r/pedroreys/~3/nibxOXo8kwU/</link>
		<comments>http://blog.pedroreys.com/2010/05/10/handling-content-type-as-we-should-through-http-headers/#comments</comments>
		<pubDate>Mon, 10 May 2010 02:08:15 +0000</pubDate>
		<dc:creator>Pedro</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Content-Type]]></category>
		<category><![CDATA[HTML Header]]></category>
		<category><![CDATA[Json]]></category>
		<category><![CDATA[XML]]></category>

		<guid isPermaLink="false">http://blog.pedroreys.com/2010/05/10/handling-content-type-as-we-should-through-http-headers/</guid>
		<description><![CDATA[In the previous post I spiked a solution to return different result types depending on a requested format. While the solution I came up with was sufficient to address the points issued on a thread at .NetArchitects, Eric Hexter hit the nail on the head with the following tweet: @pedroreys nice post on the formatter. [...]]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://blog.pedroreys.com/2010/02/07/mimicking-rails-formatter-behavior-in-asp-net-mvc/" target="_blank">previous post</a> I spiked a solution to return different result types depending on a requested format. While the solution I came up with was sufficient to address the points issued on a thread at .NetArchitects, <a href="http://www.lostechies.com/blogs/hex/" target="_blank">Eric Hexter</a> hit the nail on the head with the following <a href="http://twitter.com/ehexter/status/9712355635" target="_blank">tweet</a>:</p>
<blockquote><p>@<a href="http://twitter.com/pedroreys">pedroreys</a> nice post on the formatter. I would consider http headers instead of routing, although that is hard to manually debug</p>
</blockquote>
<p>The right way to specify the types which are accepted for the response is by using the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html" target="_blank">Accept</a> request-header. It’s been a while since Eric’s tweet, but here is the solution I came up with.</p>
<p>Lemme first define the expectations I defined:</p>
<p>If the Accept header of the request</p>
<p>- Contains <font face="Courier New">“text/html”</font> a <font face="Courier New">ViewResult</font> should be returned.</p>
<p>- Contains <font face="Courier New">“application/json”</font> and not contains “<font face="Courier New">text/html</font>” a <font face="Courier New">JsonResult</font> should be returned</p>
<p>- Contains “<font face="Courier New">text/xml</font>” and not contains “<font face="Courier New">text/html</font>” a <font face="Courier New">XmlResult</font> should be returned</p>
<p>If the requested content type can not be handled by none of the previous statements, a response with a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html" target="_blank">HTTP Status Code 406 – Not Acceptable</a> should be returned.</p>
<p>For this post. I will start with the same controller class that I used in the previous one:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class ClientController : Controller
    {
        public ActionResult Index()
        {
            var clients = new[] {
            new Client {FirstName = &quot;John&quot;, LastName = &quot;Smith&quot;},
            new Client {FirstName = &quot;Dave&quot;, LastName = &quot;Boo&quot;},
            new Client {FirstName = &quot;Garry&quot;, LastName = &quot;Foo&quot;}
                               };

            return View(clients);
        }

    }

    public class Client
    {
        public string FirstName{get;set;}

        public string LastName{get; set; }

    }</pre>
<p>&#160;</p>
<p>In order to be able to format the result based on the requested content-type on the HTTP header, I will create a base controller class that will provide this functionality to the controller. I will call it <font face="Courier New">ContentTypeAwareController</font>.</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class ContentTypeAwareController : Controller
{
   public virtual IContentTypeHandlerRepository HandlerRepository { get; set; } 

    protected ActionResult ResultWith(object model)
        {
            var handler = HandlerRepository.GetHandlerFor(HttpContext);
            return handler.ResultWith(model);
        }
    }</pre>
<p>&#160;</p>
<p>That’s it. This base class is responsible just to ask the Handler Repository for the right handler to the given HttpContext and call the ResultWith() method on the returned handler.</p>
<p>The IContentTypeHandler interface is pretty simple as well:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public interface IContentTypeHandler
{
    bool CanHandle(HttpContextBase context);
    ActionResult ResultWith(object model);
}</pre>
<p>&#160;</p>
<p>Simple and intuitive, right?</p>
<p>Let’s implement this interface then, but first let’s set the expectations as unit tests:</p>
<p>&#160;</p>
<pre class="brush: csharp;">[TestFixture]
    public class JsonHandlerTest : HandlerTestBase
    {
        [Test]
        public void should_return_a_JsonResult()
        {
            var handler = new JsonHandler();
            var result = handler.ResultWith(&quot;whatever&quot;);
            result.ShouldBeType&lt;JsonResult&gt;();
        } 

        [Test]
        public void should_Handle_request_when_content_type_requested_contains_Json()
        {
            Headers.Add(&quot;Accept&quot;, &quot;application/json&quot;); 

            var handler = new JsonHandler();
            handler.CanHandle(HttpContext).ShouldBeTrue();
        } 

        [Test]
        public void should_not_handle_request_when_content_type_requested_does_not_contain_json()
        {
            Headers.Add(&quot;Accept&quot;, &quot;text/xml&quot;); 

            var handler = new JsonHandler();
            handler.CanHandle(HttpContext).ShouldBeFalse();
        }
    }</pre>
<p>&#160;</p>
<p>To keep the post short, I will put here just the test above, all the other tests are in the solution on <a href="http://github.com/pedroreys/BlogPosts" target="_blank">github</a>. </p>
<p>The implementation of the <font face="Courier New">JsonHandler</font> is below:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class JsonHandler : IContentTypeHandler
    {
        public const string _acceptedType = &quot;application/json&quot;;
        public bool CanHandle(HttpContextBase context)
        {
            var acceptHeader = context.Request.Headers.Get(&quot;Accept&quot;); 

            return acceptHeader.Contains(_acceptedType);
        } 

        public ActionResult ResultWith(object model)
        {
            return new JsonResult
                       {
                           Data = model,
                           ContentEncoding = null,
                        JsonRequestBehavior = JsonRequestBehavior.AllowGet
                       };
        }</pre>
<p>&#160;</p>
<p>It’s important to set the value for the <font face="Courier New">JsonRequestBehavior</font> property on the <font face="Courier New">JsonResult</font> object. Otherwise you will end-up with a <font face="Courier New">InvalidOperationException</font>.</p>
<p>The other handlers are pretty straight-forward as well.</p>
<p>The one to handle requests for Xml:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class XmlHandler : IContentTypeHandler
{
    public const string _acceptedType = &quot;text/xml&quot;;

    public bool CanHandle(HttpContextBase context)
    {
        var acceptHeader = context.Request.Headers.Get(&quot;Accept&quot;);

        return acceptHeader.Contains(_acceptedType);
    }

    public ActionResult ResultWith(object model)
    {
        return new XmlResult(model);
    }
}</pre>
<p>&#160;</p>
<p>And the other to be the default, Html handler:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class HtmlHandler : IContentTypeHandler
{
    public const string _acceptedType = &quot;text/html&quot;;

    public bool CanHandle(HttpContextBase context)
    {
        var acceptHeader = context.Request.Headers.Get(&quot;Accept&quot;);

        return acceptHeader.Contains(_acceptedType);

    }

    public ActionResult ResultWith(object model)
    {
        return new ViewResult
                   {
                       ViewData = new ViewDataDictionary(model),
                   };
    }
}</pre>
<p>&#160;</p>
<p>&#160;</p>
<p>And finally, we will have a handler to return the 406 code in case of the others handlers not being able to handle the requested content type.</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class NotAcceptedContentTypeHandler : IContentTypeHandler
{
    public bool CanHandle(HttpContextBase context)
    {
        return true;
    }

    public ActionResult ResultWith(object model)
    {
        return new NotAcceptedContentTypeResult();
    }
}</pre>
<p>&#160;</p>
<p>With all that code in place, all we have left to do is to make the <font face="Courier New">ClientController</font> to inherit from the <font face="Courier New">ContentTypeAwareController</font> and call the <font face="Courier New">ResultWith()</font> method:</p>
<p>&#160;</p>
<pre class="brush: csharp;">public class ClientController : ContentTypeAwareController
{
    public ActionResult Index()
    {
        var clients = new[]{
            new Client {FirstName = &quot;John&quot;, LastName = &quot;Smith&quot;},
            new Client {FirstName = &quot;Dave&quot;, LastName = &quot;Boo&quot;},
            new Client {FirstName = &quot;Garry&quot;, LastName = &quot;Foo&quot;}
                           };

            return ResultWith(clients);
        }

    }</pre>
<p>
  </p>
<p>That’s it. The Client Controller now is able to respond to Json, Xml or Html requests. Let’s check it.</p>
<p>The web page is still being rendered as expected. Fine.</p>
<p>&#160;</p>
<p><a title="html" href="http://www.flickr.com/photos/22313104@N04/4594093858/"><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="html" src="http://farm5.static.flickr.com/4043/4594093858_af5b693db0.jpg" /></a></p>
<p>&#160;</p>
<p>But now, let’s see what responses do I get when I change the Http Header to “<font face="Courier New">application/json</font>”:</p>
<p>&#160;</p>
<p><a title="json" href="http://www.flickr.com/photos/22313104@N04/4594220022/"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" border="0" alt="json" src="http://farm5.static.flickr.com/4061/4594220022_321ba545c1.jpg" /></a></p>
<p>&#160;</p>
<p>Yeah,&#160; a Json result. Cool. What about “<font face="Courier New">text/xml</font>”:</p>
<p>&#160;</p>
<p><a title="xml" href="http://www.flickr.com/photos/22313104@N04/4593603183/"><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="xml" src="http://farm4.static.flickr.com/3391/4593603183_2b80e4c978.jpg" /></a></p>
<p>&#160;</p>
<p>Yeap, that works too. Finally, let’s see if the 406 status code is returned when an invalid content type is requested:</p>
<p>&#160;</p>
<p><a title="406" href="http://www.flickr.com/photos/22313104@N04/4594219796/"><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="406" src="http://farm2.static.flickr.com/1136/4594219796_7606432360.jpg" /></a></p>
</p>
<p>&#160;</p>
<p>So, with not so much code the Client Controller now is able to format its result based on the Content Type requested on the HTTP Header, as it should have been before. Off course this is a spike and the code can be improved. Feel free to grab it from <a href="http://github.com/pedroreys/BlogPosts" target="_blank">github</a> and improve it. </p>
<img src="http://feeds.feedburner.com/~r/pedroreys/~4/nibxOXo8kwU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.pedroreys.com/2010/05/10/handling-content-type-as-we-should-through-http-headers/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.pedroreys.com/2010/05/10/handling-content-type-as-we-should-through-http-headers/</feedburner:origLink></item>
		<item>
		<title>Mimicking Rails formatter behavior in ASP.NET MVC</title>
		<link>http://feedproxy.google.com/~r/pedroreys/~3/oxhmHbskEU0/</link>
		<comments>http://blog.pedroreys.com/2010/02/07/mimicking-rails-formatter-behavior-in-asp-net-mvc/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 18:53:08 +0000</pubDate>
		<dc:creator>Pedro</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[ASP.NET MVC]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Routes]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://blog.pedroreys.com/2010/02/07/mimicking-rails-formatter-behavior-in-asp-net-mvc/</guid>
		<description><![CDATA[I was reading this (pt-BR) thread at the brazilian .Net mailing list &#8211; dotNetArchitects – which, at first, did not have nothing to do with Rails nor output format. But, as usual, the thread deviated from the initial subject – what is not a bad thing &#8211; and somehow got into the fact that it [...]]]></description>
			<content:encoded><![CDATA[<p>I was reading <a href="http://groups.google.com/group/dotnetarchitects/browse_thread/thread/036023bee2897584?hl=pt#">this (pt-BR) thread</a> at the brazilian .Net mailing list &#8211; <a href="http://www.dotnetarchitects.net/">dotNetArchitects</a> – which, at first, did not have nothing to do with Rails nor output format. But, as usual, the thread deviated from the initial subject – what is not a bad thing &#8211; and somehow got into the fact that it would be nice to have in ASP.NET, more specifically in <a href="http://www.asp.net/mvc/">ASP.NET MVC</a>, a behavior similar to what Rails have by default to handle output formatters.</p>
<p>In Rails is possible to handle the format that will be returned by the controller as in the following example:</p>
<pre class="brush: ruby;">class PeopleController &lt; ApplicationController

def index 

@people = People.find(:all)

respond_to do |format|

format.html

format.json(render :json =&gt; @people.to_json)

format.xml(render :xml =&gt; @people.to_xml)

end

end</pre>
<p>With the controller above, if&#160; one requests the url <font face="Courier New">/people/index</font> the result will be in <font face="Courier New">html</font>. but, if <font face="Courier New">people/index.json</font> is requested instead, the result will be a <font face="Courier New">json</font> file.</p>
<p>That’s a great feature when one is developing an API and let the client code to decide the format it wants to receive the data. Unfortunately, we can’t do that out of the box with ASP.NET MVC. But, ASP.NET MVC gives us lots of extensions points and that allows us to quite easily implement the functionality to mimic this neat behavior. </p>
<p><em>First, a disclaimer. The solution that I will present is heavily based on the solution present in the routing chapter of the book <a href="http://www.amazon.com/gp/product/1933988622?ie=UTF8&amp;tag=pedroreys-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1933988622">ASP.NET MVC in Action</a>. The new edition of the book, now covering MVC 2, is, by the time I write this post, in public review. You can get more information about it on this </em><a href="http://jeffreypalermo.com/blog/mvc-2-in-action-book-conducting-public-reviews/"><em>post</em></a><em> from Jeffrey Palermo. If you are an ASP.NET developer and don’t have read the book yet, stop everything you are doing and <a href="http://www.amazon.com/gp/product/1933988622?ie=UTF8&amp;tag=pedroreys-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1933988622">go buy it now</a>.</em></p>
<p>All that said, lets have some fun.</p>
<p>In our application we have this simple Person entity:</p>
<pre class="brush: csharp;">public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}</pre>
<p>&#160;</p>
<p>The application itself is really simple, it just shows a list of People. And yes, I was lazy and used the MVC sample.</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_1" src="http://static.flickr.com/4012/4334558401_cdf8faffec.jpg" />&#160;</p>
<p>I will omit the view code for the sake of brevity as it has nothing to do with the goal of this post.</p>
<p>The <font face="Courier New">PeopleController</font> is pretty dumb too, it just returns a collection of <font face="Courier New">Person</font> to the View: </p>
<pre class="brush: csharp;">public class PeopleController : Controller
{
    public ActionResult Index()
    {
        var people = new[]
                {
                    new Person{FirstName = &quot;Joao&quot;, LastName = &quot;Silva&quot;},
                    new Person{FirstName = &quot;John&quot;, LastName = &quot;Doe&quot;},
                    new Person{FirstName = &quot;Jane&quot;, LastName = &quot;Smith&quot;}
                 };
        return View(people);
    }
}</pre>
<p>So, it works, pretty straight-forward with default routing. Now, we want to mimic the Rails formatter behavior. So, what we want is that the url <font face="Courier New">/People/Index.json</font> returns a <font face="Courier New">json</font> file instead of the html page. Ok, what we first need to do is check to see if this new url will be routed to the correct Action with the actual route configuration. </p>
<p>With the help of <a href="http://www.codeplex.com/MVCContrib">MvcContrib</a> project, we can write the following test to check if our route works as we expect:</p>
<pre class="brush: csharp;">[TestFixtureSetUp]
public void Setup()
{
    MvcApplication.RegisterRoutes(RouteTable.Routes);
}

[Test]
public void Should_map_People_url_to_people_with_default_action()
{
    &quot;~/people&quot;.Route().ShouldMapTo&lt;PeopleController&gt;(x =&gt; x.Index());
}

[Test]
public void Should_map_People_index_json_url_to_people_matching_index_action()
{
    &quot;~/people/index.json&quot;.Route().ShouldMapTo&lt;PeopleController&gt;(x =&gt; x.Index());
}</pre>
<p>As expected, the former test passes, but the latter, the one that tests the new behavior we want to test don’t. And more important, it fails as we expected it to fail.</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_2" src="http://static.flickr.com/4003/4335338096_9f9e265960.jpg" /></p>
</p>
<p>In order to make it work, we need to add a new route to our Route Dictionary.</p>
<pre class="brush: csharp;">routes.MapRoute(
&quot;Format&quot;,
&quot;{controller}/{action}.{format}/{id}&quot;,
new {id = &quot;&quot;});</pre>
<p>With this new route defined, we now get a green test. Neat.</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_3" src="http://static.flickr.com/2769/4335379468_b6e8aae0dc.jpg" /></p>
</p>
<p>With the route working and the request being routed to the right method, the controller now needs to extract the format information from the route data and handle the output format accordingly.&#160; To achieve this, I’ll create a <a href="http://martinfowler.com/eaaCatalog/layerSupertype.html">Layer SuperType</a>, a abstract class that will derive from the base <font face="Courier New">Controller</font> class. The <font face="Courier New">PeopleController</font>, then, will derive from this new class instead of the base <font face="Courier New">Controller</font> one.</p>
<p>This new Controller class, that I will name <font face="Courier New">RailsWannabeController</font>, will override the <font face="Courier New">OnActionExecuting</font> method of the Controller base class in order to extract the requested format from the <font face="Courier New">RouteData</font>. It also will have a property named <font face="Courier New">Format</font> who will store the format information. Finally, it will have a <font face="Courier New">FormatResult</font> method that returns the right <font face="Courier New">ActionResult</font> accordingly to the requested format.</p>
<p>Here is the test to ensure that <font face="Courier New">RailsWannabeController</font> correctly extracts the format information out of the <font face="Courier New">RouteData</font>.</p>
<pre class="brush: csharp;">[Test]
public void Should_extract_format_information_from_RouteData()
{
    var expectedFormat = &quot;json&quot;;
    var routeData = Stub&lt;RouteData&gt;();
    routeData.Values.Add(&quot;format&quot;,expectedFormat);

    var filterContext =
        new ActionExecutingContext()
        {
            Controller = Stub&lt;RailsWannabeController&gt;(),
            RouteData = routeData
         };

    var controller = new StubController();
    controller.ActionExecuting(filterContext);
    var requestedFormat = controller.RequestedFormat;
    Assert.AreEqual(expectedFormat,requestedFormat);
}</pre>
<p>As the <font face="Courier New">RailsWannabeController</font> will be a abstract class, a <font face="Courier New"><strike>MockController</strike> StubController</font> concrete class has to be created. This class will derive from <font face="Courier New">RailsWannabeController</font> and will have a public method to enable the <font face="Courier New">OnActionExecuting</font> method to be called. It also will have a <font face="Courier New">RequestedFormat</font> property to expose the value of the requested format extracted from the <font face="Courier New">RouteData</font>.</p>
<pre class="brush: csharp;">public class StubController : RailsWannabeController
{
    public string RequestedFormat { get { return base.Format; } }

    public void ActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
    }
}</pre>
</p>
<p><font face="Courier New">Now, all we need to do to make this test pass is code the RailsWannabeController class. </font></p>
<pre class="brush: csharp;">public class RailsWannabeController : Controller
{
    protected static string[]  ValidFormats = new [] {&quot;html&quot;,&quot;json&quot;,&quot;xml&quot;};
    protected string Format { get; set; }

    private const string formatKey = &quot;format&quot;;

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
        ExtractRequestedFormat(filterContext.RouteData.Values);
    }

    private void ExtractRequestedFormat(RouteValueDictionary routeValues)
    {
        if(routeValues.ContainsKey(formatKey))
        {
            var requestedFormat = routeValues[formatKey].ToString().ToLower();
            if(ValidFormats.Contains(requestedFormat))
            {
                Format = requestedFormat;
                return;
            }
        }
        Format = &quot;html&quot;;
    }
}</pre>
<p>Now that we got a green bar, we have to test if the <font face="Courier New">ActionResult</font> returned by the <font face="Courier New">FormatResult</font> method is from the type requested. That means that if the “<font face="Courier New">json</font>” format is passed in the <font face="Courier New">RouteData</font>, the <font face="Courier New">FomatResult</font> method the object returned must be of type <font face="Courier New">JsonResult. </font></p>
<pre class="brush: csharp;">public void Should_return_the_correct_Action_Result()
{
    var expectedFormat = &quot;json&quot;;
    var routeData = Stub&lt;RouteData&gt;();
    routeData.Values.Add(&quot;format&quot;, expectedFormat);

    var filterContext = new ActionExecutingContext()
    {
        Controller = Stub&lt;RailsWannabeController&gt;(),
        RouteData = routeData
    };

    var controller = new StubController();
    controller.ActionExecuting(filterContext);

    var people = new[]{
                         new Person{FirstName = &quot;Joao&quot;, LastName = &quot;Silva&quot;},
                         new Person{FirstName = &quot;John&quot;, LastName = &quot;Doe&quot;},
                         new Person{FirstName = &quot;Jane&quot;, LastName = &quot;Smith&quot;}
                     };

    var formattedResult = controller.GetFormattedResult(people);
    Assert.AreEqual(typeof(JsonResult),formattedResult.GetType());
}</pre>
<p>&#160;</p>
<p>There is a LOT of code in this test. Much more then I’d like it to have. But to keep the code as explicit as possible, for sake of clarity, I left it that way. I’ll let the refactoring of this code as an exercise for the reader.</p>
<p>As you may guess from the code above, the <font face="Courier New"><strike>MockController</strike> StubController</font> class had to be modified to include the <font face="Courier New">GetFormattedResult</font> method.</p>
<pre class="brush: csharp;">public class StubController : RailsWannabeController
{
    public string RequestedFormat { get { return base.Format; } }

    public void ActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);
    }

    public ActionResult GetFormattedResult(object model)
    {
        return base.FormatResult(model);
    }
}</pre>
<p>&#160;</p>
<p>In the&#160; <font face="Courier New">RailsWannabeController</font> we have to create a <font face="Courier New">FormatResult</font> method that, as it name states, format the result accordingly to the format requested.</p>
<pre class="brush: csharp;">protected ActionResult FormatResult(object model)
{
    switch (Format)
    {
        case &quot;html&quot;:
            return View(model);
        case &quot;json&quot;:
            return Json(model);
        case &quot;xml&quot;:
            return new XmlResult(model);
        default:
            throw new FormatException(
                string.Format(&quot;The format \&quot;{0}\&quot; is invalid&quot;, Format));
    }
}</pre>
<p>ASP.NET MVC framework gives us the <font face="Courier New">Json</font> method out of the box. The <font face="Courier New">XmlResult</font> is provided by the MvcContrib project.</p>
<p>Now, all we have to do is change the <font face="Courier New">PeopleController</font> class to derive from the Layer SuperType instead of the Controller base class. And change the <font face="Courier New">View()</font> method call to be a call to the <font face="Courier New">FormatResult</font> method.</p>
<pre class="brush: csharp;">public class PeopleController : RailsWannabeController
{
    public ActionResult Index()
    {
        var people = new[]
            {
                new Person{FirstName = &quot;Joao&quot;, LastName = &quot;Silva&quot;},
                new Person{FirstName = &quot;John&quot;, LastName = &quot;Doe&quot;},
                new Person{FirstName = &quot;Jane&quot;, LastName = &quot;Smith&quot;}
             };
        return FormatResult(people);
    }
}</pre>
<p>OK, all the tests are green and we are done coding. Let’s check if all we’ve done works properly.</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_4" src="http://static.flickr.com/4068/4337240149_0c587a80fd.jpg" /></p>
<p>Using the default route we get the same result. Great. </p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_6" src="http://static.flickr.com/4070/4337983998_793d67231f.jpg" /></p>
<p>If “json” format is provided in the URL we get a <font face="Courier New">json</font> file instead. Woot.</p>
<p><img style="display: block; float: none; margin-left: auto; margin-right: auto" border="0" alt="Rails_MVC_7" src="http://static.flickr.com/4011/4337240393_cf05be4942.jpg" /></p>
<p>Finally, requesting a xml we get the result in a XML file. That’s it we are done.</p>
<p>I know the post is a little bit long, but that’s because my intention was to explicit all the process of mimicking the behavior of the Rails formatter. And, as you should do as well, I managed to have the code I was working on to be covered by tests that gave me the confidence that I wasn’t breaking anything while I was making the changes. It is specially important to cover your routes with tests as route changes can introduce some hard to find bugs. I hope this post helps to show that, although ASP.NET MVC may not have all the features we want it to have, it’s high extensibility allows us to extend it and easily introduce new behaviors.</p>
<p>As I’m not a native English speaker, I ask and encourage you to point out not only technical mistakes but also any language related mistakes that I’ve made at this post. </p>
<p><strong>UPDATE:</strong> As Giovanni correctly pointed out in his comment, the <font face="Courier New">MockController</font> class is not a Mock but a Stub. I renamed the class to <font face="Courier New">StubController</font> to avoid misunderstandings. Thanks, Giovanni. </p>
<img src="http://feeds.feedburner.com/~r/pedroreys/~4/oxhmHbskEU0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.pedroreys.com/2010/02/07/mimicking-rails-formatter-behavior-in-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		<feedburner:origLink>http://blog.pedroreys.com/2010/02/07/mimicking-rails-formatter-behavior-in-asp-net-mvc/</feedburner:origLink></item>
		<item>
		<title>Alternative MBA with Seth Godin</title>
		<link>http://feedproxy.google.com/~r/pedroreys/~3/-eDfkHPMDAU/</link>
		<comments>http://blog.pedroreys.com/2008/12/03/alternative-mba-with-seth-godin/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 20:24:23 +0000</pubDate>
		<dc:creator>Pedro</dc:creator>
				<category><![CDATA[Recomendations]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[coach]]></category>
		<category><![CDATA[internship]]></category>
		<category><![CDATA[marketing]]></category>
		<category><![CDATA[opportunity]]></category>

		<guid isPermaLink="false">http://blog.pedroreys.com/?p=25</guid>
		<description><![CDATA[Look this trade-off: Instead of getting a MBA, spend 6 months at the office of one of the greatest marketing authors and blogger. That&#8217;s what Seth Godin is offering. Quoting him, what he offers is: Six intense months working with a few other amazing people (and me.) It is a really awesome opportunity for one [...]]]></description>
			<content:encoded><![CDATA[<p>Look this trade-off: Instead of getting a MBA, spend 6 months at the office of one of the greatest marketing authors and blogger.</p>
<p>That&#8217;s what <a href="http://sethgodin.typepad.com/" target="_blank">Seth Godin</a> is <a href="http://www.squidoo.com/Alternative-MBA" target="_blank">offering</a>. Quoting him, what he offers is:</p>
<blockquote><p>Six intense months working with a few other amazing people (and me.)</p></blockquote>
<p>It is a really awesome opportunity for one who already lives or can afford the expenses of living 6 months in NYC.</p>
<p>It is not everyday that one <span style="text-decoration: line-through;">have</span> has the chance to get 6 months of coaching and learning from someone like Seth, and for <strong>free</strong>.</p>
<p>Source: <a href="http://www.squidoo.com/Alternative-MBA" target="_blank">Squiido</a> via <a href="http://scrum4you.wordpress.com/2008/12/02/seth-godin-offers-you-a-huge-opportunity-go-for-it/" target="_blank">Scrum4You</a></p>
<img src="http://feeds.feedburner.com/~r/pedroreys/~4/-eDfkHPMDAU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.pedroreys.com/2008/12/03/alternative-mba-with-seth-godin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.pedroreys.com/2008/12/03/alternative-mba-with-seth-godin/</feedburner:origLink></item>
		<item>
		<title>Hi!</title>
		<link>http://feedproxy.google.com/~r/pedroreys/~3/h2tBbTE1IN0/</link>
		<comments>http://blog.pedroreys.com/2008/11/03/hi/#comments</comments>
		<pubDate>Mon, 03 Nov 2008 17:37:00 +0000</pubDate>
		<dc:creator>Pedro</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Hello World]]></category>

		<guid isPermaLink="false">http://pedroreys.com/blog/?p=7</guid>
		<description><![CDATA[Hi everybody. This is the first post of my new blog. Some of you may be familiar with the Portuguese written blog that I co-author with Jorge Maia. At this one I&#8217;ll be writing in English only, I hope. :) Well, as soon as I finish all the WordPress settings, I will start to post [...]]]></description>
			<content:encoded><![CDATA[<p>Hi everybody.</p>
<p>This is the first post of my new blog.</p>
<p>Some of you may be familiar with the Portuguese written <a href="http://www.gerenciamentoagil.com.br" target="_blank">blog</a> that I co-author with Jorge Maia. At this one I&#8217;ll be writing in English only, I hope. :)</p>
<p>Well, as soon as I finish all the WordPress settings, I will start to post here.</p>
<p>For you who don&#8217;t know me yet, I suggest reading the &#8220;<a href="http://blog.pedroreys.com/?page_id=2" target="_blank">About</a>&#8221; section.</p>
<p>Cheers,</p>
<p>Pedro Reys</p>
<img src="http://feeds.feedburner.com/~r/pedroreys/~4/h2tBbTE1IN0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.pedroreys.com/2008/11/03/hi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.pedroreys.com/2008/11/03/hi/</feedburner:origLink></item>
	</channel>
</rss>
