<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Twist of Life &#187; MVC</title>
	<atom:link href="http://www.sethwebster.com/tag/mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sethwebster.com</link>
	<description>on the web, with Seth Webster</description>
	<lastBuildDate>Tue, 21 Jun 2011 00:11:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Format Filter for ASP.NET MVC &#8212; getting a little more RESTful.</title>
		<link>http://www.sethwebster.com/2009/05/14/format-filter-for-aspnet-mvc-getting-a-little-more-restful/</link>
		<comments>http://www.sethwebster.com/2009/05/14/format-filter-for-aspnet-mvc-getting-a-little-more-restful/#comments</comments>
		<pubDate>Thu, 14 May 2009 11:08:00 +0000</pubDate>
		<dc:creator>Seth Webster</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[AspNet]]></category>
		<category><![CDATA[CSharp]]></category>
		<category><![CDATA[MVC]]></category>

		<guid isPermaLink="false">http://blog.sethwebster.com/blog/2009/05/15/Format-filter-for-aspnet-mvc-getting-a-little-more-restful.xhtml</guid>
		<description><![CDATA[I developing http://nsfw4.me, I wanted a closer-to-automated way to add extension based format filtering to the different controller methods. For integration&#8217;s sake, I wanted the clients which may adopt using nsfw4.me to have an easy way to interact and understand what the outcomes of those interactions were.  In building this site on Microsoft&#8217;s newly released [...]]]></description>
			<content:encoded><![CDATA[<div style="background-color: #ffffff; display: block; font-family: verdana, arial, helvetica, sans-serif; font-size: 11px;">
<p>I developing http://nsfw4.me, I wanted a closer-to-automated way to add extension based format filtering to the different controller methods. For integration&#8217;s sake, I wanted the clients which may adopt using <a href="http://nsfw4.me">nsfw4.me</a> to have an easy way to interact and understand what the outcomes of those interactions were.  In building this site on Microsoft&#8217;s newly released MVC framework,it was easy to create a RESTful interface,but I didn&#8217;t see a baked in way to format output based on requested extension.</p>
<p>The approach I took was create two new route entries in Global.asax.cs:<br />
<span style="white-space: normal;"> </span></p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre>      <span class="lnum">1:</span></pre>
<pre>      <span class="lnum">2:</span> routes.MapRoute(<span class="str">"DefaultFormat"</span>, <span class="str">"{controller}/{action}.{format}"</span>,</pre>
<pre>      <span class="lnum">3:</span>      <span class="kwrd">new</span> { controller = <span class="str">"Home"</span>, action = <span class="str">"Index"</span>, id = <span class="str">""</span>, format = <span class="str">"html"</span>});</pre>
<pre>      <span class="lnum">4:</span></pre>
<pre>      <span class="lnum">5:</span> routes.MapRoute(<span class="str">"DefaultFormat"</span>,<span class="str">"{controller}/{action}/{id}.{format}"</span>,</pre>
<pre>      <span class="lnum">6:</span>      <span class="kwrd">new</span> { controller = <span class="str">"Home"</span>, action = <span class="str">"Index"</span>,id = <span class="str">""</span>, format = <span class="str">"html"</span>});</pre>
<pre>      <span class="lnum">7:</span></pre>
<pre>      <span class="lnum">8:</span></pre>
</div>
<p>Now, I would be able to pick up an extension on the requested path and act accordingly. For example, if someone visits a details link for a given object, and they want .xml, then I can give them a serialized version of that data to suit their needs.  If someone visits with the default .html (or nothing at all) we can give standard html rendering.</p>
<p>Enter the FormatFilterAttribute class.  This class hangs on a controller method and works its magic in the OnActionExecutedmethod.  It is in this method that we make the determination on how to handle the request.</p>
<p><span style="font-weight: bold;">Note:</span> This filter requires <a href="http://james.newtonking.com/">James Newton-King&#8217;s JSON Library</a>.</p>
<p><!-- code formatted by http://manoli.net/csharpformat/ --></p>
<div class="csharpcode">
<pre>      <span class="lnum">1:</span>      <span class="kwrd">public</span>      <span class="kwrd">override</span>      <span class="kwrd">void</span> OnActionExecuted(ActionExecutedContext filterContext)</pre>
<pre>      <span class="lnum">2:</span>         {</pre>
<pre>      <span class="lnum">3:</span>      <span class="kwrd">if</span> (filterContext.RouteData.Values.ContainsKey(<span class="str">"format"</span>))</pre>
<pre>      <span class="lnum">4:</span>             {</pre>
<pre>      <span class="lnum">5:</span>                 var fmt = GetFormat(filterContext);</pre>
<pre>      <span class="lnum">6:</span>                 var obj = GetResultObject(filterContext);</pre>
<pre>      <span class="lnum">7:</span>      <span class="kwrd">switch</span> (fmt)</pre>
<pre>      <span class="lnum">8:</span>                 {</pre>
<pre>      <span class="lnum">9:</span>      <span class="kwrd">case</span>      <span class="str">"xml"</span>:</pre>
<pre>      <span class="lnum">10:</span>      <span class="kwrd">if</span> (<span class="kwrd">null</span> != obj)</pre>
<pre>      <span class="lnum">11:</span>                         {</pre>
<pre>      <span class="lnum">12:</span>                             XmlSerializer xs = <span class="kwrd">new</span> XmlSerializer(obj.GetType());</pre>
<pre>      <span class="lnum">13:</span>      <span class="kwrd">using</span> (MemoryStream Ms = <span class="kwrd">new</span> MemoryStream())</pre>
<pre>      <span class="lnum">14:</span>                             {</pre>
<pre>      <span class="lnum">15:</span>                                 xs.Serialize(Ms, obj);</pre>
<pre>      <span class="lnum">16:</span>                                 var ret = System.Text.Encoding.UTF8.GetString(Ms.ToArray());</pre>
<pre>      <span class="lnum">17:</span>                                 filterContext.Result =<span class="kwrd">new</span> PlainTextActionResult(ret);</pre>
<pre>      <span class="lnum">18:</span>                             }</pre>
<pre>      <span class="lnum">19:</span>                         }</pre>
<pre>      <span class="lnum">20:</span>      <span class="kwrd">break</span>;</pre>
<pre>      <span class="lnum">21:</span>      <span class="kwrd">case</span>      <span class="str">"json"</span>:</pre>
<pre>      <span class="lnum">22:</span>      <span class="kwrd">if</span> (<span class="kwrd">null</span> != obj)</pre>
<pre>      <span class="lnum">23:</span>                         {</pre>
<pre>      <span class="lnum">24:</span>                             filterContext.Result =<span class="kwrd">new</span> PlainTextActionResult(</pre>
<pre>      <span class="lnum">25:</span>                                 JsonConvert.SerializeObject(obj, Formatting.Indented));</pre>
<pre>      <span class="lnum">26:</span>                         }</pre>
<pre>      <span class="lnum">27:</span>      <span class="kwrd">break</span>;</pre>
<pre>      <span class="lnum">28:</span>      <span class="kwrd">case</span>      <span class="str">"html"</span>:</pre>
<pre>      <span class="lnum">29:</span>      <span class="rem">//DO NOTHING</span></pre>
<pre>      <span class="lnum">30:</span>      <span class="kwrd">break</span>;</pre>
<pre>      <span class="lnum">31:</span>      <span class="kwrd">default</span>:</pre>
<pre>      <span class="lnum">32:</span>      <span class="kwrd">throw</span>      <span class="kwrd">new</span> ArgumentException(<span class="str">"Invalid format supplied"</span>);</pre>
<pre>      <span class="lnum">33:</span>      <span class="kwrd">break</span>;</pre>
<pre>      <span class="lnum">34:</span>                 }</pre>
<pre>      <span class="lnum">35:</span>             }</pre>
<pre>      <span class="lnum">36:</span>      <span class="kwrd">base</span>.OnActionExecuted(filterContext);</pre>
<pre>      <span class="lnum">37:</span>         }</pre>
<pre>      <span class="lnum">38:</span></pre>
</div>
<p><span style="font-weight: bold;">What&#8217;s happening Here?</span></p>
<p>As the MVC framework processes the request to this method, we will intercept after the user code has run.  At this time we determine whether there was request for something other than a standard render and act accordingly.  If a ViewDataKey has been set for the attribute, we look for this object in the ViewDatacollection, if no key is specified, we try getting the data from the Model property of the current ViewData.  This data is then serialized back to the requesting client.  Currently, 2 formats are supported: xml and json.</p>
<p>Try it here:</p>
<p>HTML: <a href="http://nsfw4.me/links/details/yahoo">http://nsfw4.me/links/details/yahoo</a></p>
<p>JSON:  <a href="http://nsfw4.me/links/details/yahoo.json">http://nsfw4.me/links/details/yahoo.json</a></p>
<p>XML:  <a href="http://nsfw4.me/links/details/yahoo.xml">http://nsfw4.me/links/details/yahoo.xml</a></p>
<p>It also works with creating data.   If you post the proper values (LinkId, LinkUrl) to http://nsfw4.me/links/create.xml, you will receive the result, good or bad in xml format.  The same also applies for .json requests.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sethwebster.com/2009/05/14/format-filter-for-aspnet-mvc-getting-a-little-more-restful/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

