<?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/" version="2.0">

<channel>
	<title>Elegant Code</title>
	
	<link>http://elegantcode.com</link>
	<description />
	<lastBuildDate>Sat, 07 Nov 2009 23:08:41 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ElegantCode" type="application/rss+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
		<title>Asp.Net MVC JavaScriptView</title>
		<link>http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/</link>
		<comments>http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 23:08:41 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/</guid>
		<description><![CDATA[For a while now I’ve wanted the ability to generate javascript file like I generate html files.&#160; Take a little bit of the power of the WebForm view engine (just a little bit) and give that to me for JavaScript.
Why?&#160; I have a few reasons.&#160; Number one is I want to remove all of my [...]]]></description>
			<content:encoded><![CDATA[<p>For a while now I’ve wanted the ability to generate javascript file like I generate html files.&#160; Take a little bit of the power of the WebForm view engine (just a little bit) and give that to me for JavaScript.</p>
<p>Why?&#160; I have a few reasons.&#160; Number one is I want to remove all of my JavaScript from the html, so the JavaScript is loaded via script tags.&#160; Once that happens, then I can have the JavaScript cached by the browser and speed up my application a bit.&#160; What I need the Asp.Net engine for was to give me accurate links to web site resources (images, web services, call, other javascript files, etc).&#160; These are thing that I don’t want to hard wire, mostly because I’ve bitten off the Asp.Net Routing engine bug.&#160; So, I want to use the Asp.Net Routing engine to tell me where to find stuff.</p>
<p>Not that I’ve committed to Asp.Net MVC I’ve come to a realization that making dynamic javascript files is well within my reach.&#160; Actually, it is almost there already; Asp.Net MVC ships with a JavaScriptResult.&#160; The downside of that result action is that the object expects you to hand it the JavaScript as a string, which it pushes to the browser as a file.&#160; I want to give a method a JavaScript View for that.&#160; The other good news about JavaScriptResult is that it doesn’t do much (just set the response.ContentType&#160; to application/x-javascript).&#160; So I could grab all of the View methods, turn them into extension methods, rename them, and then use them for my own underhanded affairs.</p>
<p>Luckily we can all grab the Asp.Net MVC source code and go to town.&#160; I didn’t modify the original source, but I defined a new class (JavaScriptFileResult) and a bunch of extension methods for the Asp.Net MVC Controller to give you JavaScriptView methods.&#160; You can see a usage in the first piece of code.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> ActionResult JsConstants( )</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>.JavaScriptView();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>Now below is the actually extension methods and class needed.&#160; Put this in your project some place and go to down.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> JavaScriptFileResult: ViewResult</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">override</span> <span style="color: #0000ff">void</span> ExecuteResult(ControllerContext context)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #0000ff">base</span>.ExecuteResult(context);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>         HttpResponseBase response = context.HttpContext.Response;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         response.ContentType = <span style="color: #006080">&quot;application/x-javascript&quot;</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">class</span> JavaScriptControllerExtensions</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller )</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, <span style="color: #0000ff">null</span> <span style="color: #008000">/* viewName */</span>, <span style="color: #0000ff">null</span> <span style="color: #008000">/* masterName */</span>, <span style="color: #0000ff">null</span> <span style="color: #008000">/* model */</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, <span style="color: #0000ff">object</span> model)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20">  20:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, <span style="color: #0000ff">null</span> <span style="color: #008000">/* viewName */</span>, <span style="color: #0000ff">null</span> <span style="color: #008000">/* masterName */</span>, model);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21">  21:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22">  22:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23">  23:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, <span style="color: #0000ff">string</span> viewName)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24">  24:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum25">  25:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, viewName, <span style="color: #0000ff">null</span> <span style="color: #008000">/* masterName */</span>, <span style="color: #0000ff">null</span> <span style="color: #008000">/* model */</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum26">  26:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum27">  27:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum28">  28:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, <span style="color: #0000ff">string</span> viewName, <span style="color: #0000ff">string</span> masterName)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum29">  29:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum30">  30:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, viewName, masterName, <span style="color: #0000ff">null</span> <span style="color: #008000">/* model */</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum31">  31:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum32">  32:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum33">  33:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, <span style="color: #0000ff">string</span> viewName, <span style="color: #0000ff">object</span> model)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum34">  34:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum35">  35:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, viewName, <span style="color: #0000ff">null</span> <span style="color: #008000">/* masterName */</span>, model);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum36">  36:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum37">  37:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum38">  38:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, <span style="color: #0000ff">string</span> viewName, <span style="color: #0000ff">string</span> masterName, <span style="color: #0000ff">object</span> model)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum39">  39:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum40">  40:</span>         <span style="color: #0000ff">if</span>( model != <span style="color: #0000ff">null</span> )</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum41">  41:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum42">  42:</span>             controller.ViewData.Model = model;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum43">  43:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum44">  44:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum45">  45:</span>         <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> JavaScriptFileResult</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum46">  46:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum47">  47:</span>             ViewName = viewName,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum48">  48:</span>             MasterName = masterName,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum49">  49:</span>             ViewData = controller.ViewData,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum50">  50:</span>             TempData = controller.TempData</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum51">  51:</span>         };</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum52">  52:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum53">  53:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum54">  54:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, IView view)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum55">  55:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum56">  56:</span>         <span style="color: #0000ff">return</span> JavaScriptView(controller, view, <span style="color: #0000ff">null</span> <span style="color: #008000">/* model */</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum57">  57:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum58">  58:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum59">  59:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> ViewResult JavaScriptView(<span style="color: #0000ff">this</span> Controller controller, IView view, <span style="color: #0000ff">object</span> model)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum60">  60:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum61">  61:</span>         <span style="color: #0000ff">if</span>( model != <span style="color: #0000ff">null</span> )</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum62">  62:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum63">  63:</span>             controller.ViewData.Model = model;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum64">  64:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum65">  65:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum66">  66:</span>         <span style="color: #0000ff">return</span> <span style="color: #0000ff">new</span> JavaScriptFileResult</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum67">  67:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum68">  68:</span>             View = view,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum69">  69:</span>             ViewData = controller.ViewData,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum70">  70:</span>             TempData = controller.TempData</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum71">  71:</span>         };</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum72">  72:</span>     }</pre>
<p><!--CRLF--></div>
</div>
<p>&#160;</p>
<p>Now the view, here is what it looks like:</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> &lt;%@ Control Language=<span style="color: #006080">&quot;C#&quot;</span> Inherits=<span style="color: #006080">&quot;System.Web.Mvc.ViewUserControl&quot;</span> %&gt;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> <span style="color: #0000ff">var</span> UrlList = {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     SubscriptionList: <span style="color: #006080">'&lt;%=Url.Action(&quot;SubscriptionList&quot;, &quot;Channel&quot;) %&gt;'</span>,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     MoreSubscriptions: <span style="color: #006080">'&lt;%=Url.Action(&quot;More&quot;, &quot;Channel&quot;) %&gt;'</span>,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     WaitGif: <span style="color: #006080">'&lt;%=Url.Content(&quot;~/Content/img/ajaxloader.gif&quot;) %&gt;'</span>,</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span> };</pre>
<p><!--CRLF--></div>
</div>
<p>Like I stated before, I was looking to get uris for the most part.&#160; But this could also be a strongly typed view where you have to pass in real data.</p>
<p>Finally, loading this view into my page.&#160; You saw the controller action was “JsConstants” above, which was in my HomeController (not shown), so here is how I ask the routing engine for the JavaScript file.</p>
<div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">script</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">=&quot;text/javascript&quot;</span> <span style="color: #ff0000">src</span><span style="color: #0000ff">=&quot;&lt;%=Url.Content(&quot;</span>~/<span style="color: #ff0000">Home</span>/<span style="color: #ff0000">JsConstants</span><span style="color: #0000ff">&quot;) %&gt;&quot;</span><span style="color: #0000ff">&gt;&lt;/</span><span style="color: #800000">script</span><span style="color: #0000ff">&gt;</span></pre>
<p><!--CRLF--></div>
</div>
<p>&#160;</p>
<p>So far I am happy with this technique.&#160; But if you see something that can be improved, please let me know.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=GoGu-VM8GMk:1bXmJR0Pxiw:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=GoGu-VM8GMk:1bXmJR0Pxiw:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=GoGu-VM8GMk:1bXmJR0Pxiw:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=GoGu-VM8GMk:1bXmJR0Pxiw:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=GoGu-VM8GMk:1bXmJR0Pxiw:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=GoGu-VM8GMk:1bXmJR0Pxiw:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/GoGu-VM8GMk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Massive Search &amp; Replace Among Files Checked-in to TFS</title>
		<link>http://elegantcode.com/2009/11/07/massive-search-replace-among-files-checked-in-to-tfs/</link>
		<comments>http://elegantcode.com/2009/11/07/massive-search-replace-among-files-checked-in-to-tfs/#comments</comments>
		<pubDate>Sat, 07 Nov 2009 21:01:29 +0000</pubDate>
		<dc:creator>Jason Jarrett</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/07/massive-search-replace-among-files-checked-in-to-tfs/</guid>
		<description><![CDATA[This post is a note to myself, as the two outlined below contain code/commands I’ve done (wished I could have done automatically in the past) that I want to save for reference later.
I spent the last (almost full year) taking baby steps in an effort to make our logic layer a tiny smidgen eency weency [...]]]></description>
			<content:encoded><![CDATA[<p>This post is a note to myself, as the two outlined below contain code/commands I’ve done (wished I could have done automatically in the past) that I want to save for reference later.</p>
<p>I spent the last (almost full year) taking baby steps in an effort to make our logic layer a tiny smidgen eency weency bit more testable. Trust me, trying to replace <strong>an everything’s a Singleton architecture is no easy task</strong>. I won’t go into my strong dislike for Singletons – take a look at <a href="http://tinyurl.com/yl8bnhj">Singletons are Evil</a>. I’ve slowly worn the team down into an agreement that we will not propagate any more Singletons in the project.&#160; They’ve given me a new saying “Read my lips. NO NEW SINGLETONS!”.</p>
<ol>
<h5>PowerShell assisted regular expression search and replace.</h5>
<p>In my case, the specific regular expression needed to find</ol>
<pre class="brush: csharp;">SomeBusinessLogicClass.Instance.SomeFooMethod(bar);

//  and replace it with 
Resolve&lt;ISomeBusinessLogicClass&gt;().SomeFooMethod(bar); 
</pre>
<p>Below is the PowerShell script I used.</p>
<p># define the find and replacement regular expressions.<br />
  <br />$regex_find = &#8216;([a-zA-Z]+)\.Instance\.&#8217; </p>
<p>$regex_replace = &#8216;Resolve&lt;I$1&gt;().&#8217; </p>
<p># get all the C# files we want to search/replace through<br />
  <br />$allFiles = Get-ChildItem -Filter *.cs -Recurse </p>
<p>foreach($fileToReplace in $allFiles)<br />
  <br />{ </p>
<p>&#160;&#160;&#160; $fileString = $fileToReplace.FullName </p>
<p>&#160;&#160;&#160; if([String]::Join([Environment]::NewLine, (Get-Content -Path $fileString)) -match $regex_find)<br />
  <br />&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; # make the file writable so we can update it </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; $fileToReplace.IsReadOnly = $false; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Write-Host &quot;applying fix to &#8211; $fileString&quot; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; # here’s where we load up the file iterate through each line&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; # replace any of the regex matches </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; # and save the file back to the original location </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; Set-Content $fileString -Value ((Get-Content -Path $fileString) | foreach { if( $_ -match $regex_find) { $_ -replace $regex_find, $regex_replace } else { $_ } } ) </p>
<p>&#160;&#160;&#160; } </p>
<p>}</p>
<p>&#160;</p>
<blockquote>
<p>Caveat:</p>
<ul>
<li>Some of the files “end of file” changed (added an extra end line in some cases)</li>
</ul>
</blockquote>
<p>&#160;</p>
<h5>Team Foundation Server tip to detect the changed files.</h5>
<p>&#160;</p>
<p>The next step requires you install the <a href="http://msdn.microsoft.com/en-us/teamsystem/bb980963.aspx">TFS Power Tools</a>.</p>
<p>Once installed, fire up the PowerShell console given in the start menu</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2009/11/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://elegantcode.com/wp-content/uploads/2009/11/image_thumb.png" width="278" height="427" /></a> </p>
<p>I then ran the following command to have all edited files automatically detected as modified and can then be set as pending a change in TFS.</p>
<blockquote>
<p>
    <br />tfpt online /adds /diff /recursive . </p>
</blockquote>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=DxAUJO7Sdqk:2AvuuMODMt4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=DxAUJO7Sdqk:2AvuuMODMt4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=DxAUJO7Sdqk:2AvuuMODMt4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=DxAUJO7Sdqk:2AvuuMODMt4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=DxAUJO7Sdqk:2AvuuMODMt4:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=DxAUJO7Sdqk:2AvuuMODMt4:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/DxAUJO7Sdqk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/07/massive-search-replace-among-files-checked-in-to-tfs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using serialized JSON to move complex data to and from the browser</title>
		<link>http://elegantcode.com/2009/11/06/using-serialized-json-to-move-complex-data-to-and-from-the-browser/</link>
		<comments>http://elegantcode.com/2009/11/06/using-serialized-json-to-move-complex-data-to-and-from-the-browser/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 23:37:30 +0000</pubDate>
		<dc:creator>Jason Grundy</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/06/using-serialized-json-to-move-complex-data-to-and-from-the-browser/</guid>
		<description><![CDATA[Jarod and I have both been working on a FubuMVC application for one of our Guild 3 clients. It’s been great to have the opportunity to work with a different MVC framework and hopefully we’ll comment on what we did and didn’t like about Fubu in a follow up post. I should note at this [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://elegantcode.com/author/ferguson/feed/">Jarod</a> and I have both been working on a <a href="http://code.google.com/p/fubumvc/">FubuMVC</a> application for one of our <a href="http://guild3.com">Guild 3</a> clients. It’s been great to have the opportunity to work with a different MVC framework and hopefully we’ll comment on what we did and didn’t like about Fubu in a follow up post. I should note at this point that the technique outlined below is not limited to Fubu, in fact it would also work with ASP.NET MVC or even Web Forms.</p>
<p>On one of the Views I had to move a collection of complex data from the client to the server. By complex I mean more than just a single property. An example of this might be editable rows in a table (yes I know that there are other ways to solve this problem such as using AJAX but please stick with me). In addition I didn’t like the fact that there was a duplication of the presentation logic – server side binding during the initial rendering and client side binding if data was changed. I’ve seen a lot of bugs in the past with this approach when someone makes server or client side changes but forgets about the other piece.</p>
<p>I decided to used JSON as a common currency for this part of the UI. I removed the server side binding. Then on the server side I created a Display Model (a View Model for a subset of the View) to represent the data that I needed to display and edit. I can serialize this to JSON (new JavaScriptSerializer().Serialize(myDisplayModel)). I can subsequently access the JSON via an AJAX request or I can stuff it into the DOM if I am sensitive about the number of calls being made (which I was here). On the client side I used a <a href="http://code.google.com/p/jquery-json/">JQuery plugin</a> ($.evalJSON(myJsonString)) to convert the JSON into a form that is easily consumable in Javascript. I could therefore use the same code to initially populate the UI and deal with any edits.</p>
<p>When an edit was made I simply update the UI and store the new JSON in the DOM ($.toJSON(myJSonObject)). When the form was submitted back to the server I can easily deserialize the JSON (new JavaScriptSerializer().Deserialize&lt;myDisplayModel&gt;(myJsonString);) and then manipulate it as I see fit.</p>
<p>What is nice about this technique is it allows both the client and the server to work with the same Display Model. It also resulted in nice clean “object.Property” Javascript.</p>
<p>As always any feedback or alternative approaches would be greatly appreciated.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=7ZwRShegvew:H6W3GhI7vNA:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=7ZwRShegvew:H6W3GhI7vNA:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=7ZwRShegvew:H6W3GhI7vNA:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=7ZwRShegvew:H6W3GhI7vNA:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=7ZwRShegvew:H6W3GhI7vNA:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=7ZwRShegvew:H6W3GhI7vNA:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/7ZwRShegvew" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/06/using-serialized-json-to-move-complex-data-to-and-from-the-browser/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Form – Storm – Norm – Perform</title>
		<link>http://elegantcode.com/2009/11/02/form-storm-norm-perform/</link>
		<comments>http://elegantcode.com/2009/11/02/form-storm-norm-perform/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 20:49:45 +0000</pubDate>
		<dc:creator>Jason Grundy</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/02/form-storm-norm-perform/</guid>
		<description><![CDATA[As you probably know by now three Elegant Coders (Jarod, David and myself) have recently formed Guild 3 Software.
One of the reasons that we were keen to work together is that we have a lot of shared values, not least of which are Integrity, Craftsmanship, Agility and Community. However we had not worked together before. [...]]]></description>
			<content:encoded><![CDATA[<p>As you <a href="http://elegantcode.com/2009/10/20/introducing-guild-3-software/">probably know by now</a> three Elegant Coders (<a href="http://elegantcode.com/author/ferguson/feed/">Jarod</a>, <a href="http://feeds2.feedburner.com/DStarr">David</a> and myself) have recently formed <a href="http://www.guild3.com/">Guild 3 Software</a>.</p>
<p>One of the reasons that we were keen to work together is that we have a lot of shared values, not least of which are <a href="http://guild3.com/founding-values">Integrity, Craftsmanship, Agility and Community</a>. However we had not worked together before. And despite our ideological common ground there are always challenges with any new team. One method of visualizing the stages that you typically go through in this scenario is a model known as <a href="http://en.wikipedia.org/wiki/Forming-storming-norming-performing">Form – Storm – Norm – Perform</a>.</p>
<p>I’m not going to explain the concept as the referenced Wikipedia article does an excellent job of that. However I do want to emphasize that any subsequent changes in the team or the context within which it operates take everyone back to the beginning of the process. Of course if the change is small then the duration of the cycle will often be commensurately short. Understanding the process that we were going through and its psychological ramifications has certainly enabled us to be successful. I hope that it helps you too.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=m_sJXw2YZVg:4yF_AMs_jXk:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=m_sJXw2YZVg:4yF_AMs_jXk:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=m_sJXw2YZVg:4yF_AMs_jXk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=m_sJXw2YZVg:4yF_AMs_jXk:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=m_sJXw2YZVg:4yF_AMs_jXk:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=m_sJXw2YZVg:4yF_AMs_jXk:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/m_sJXw2YZVg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/02/form-storm-norm-perform/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>State Pattern, Enumeration Class and Fluent NHibernate (Oh my!)</title>
		<link>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/</link>
		<comments>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 04:20:10 +0000</pubDate>
		<dc:creator>Richard Cirerol</dc:creator>
				<category><![CDATA[.Net 3.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Fluent NHibernate;State Pattern;Enumeration]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/</guid>
		<description><![CDATA[Recently, I needed to change a basic enumeration into a full-fledged state pattern. After getting all my domain classes updated, I began reviewing the persistence layer. And I hit a wall.  I wasn’t sure how I wanted to update my Fluent NHibernate convention to persist the current state.]]></description>
			<content:encoded><![CDATA[<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shCore.css" />
<link type="text/css" rel="stylesheet" href="http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css" />
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js"></script><br />
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js"></script><br />
<script type="text/javascript" src="http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf"></script><br />
<script type="text/javascript">
            SyntaxHighlighter.all();
            dp.SyntaxHighlighter.HighlightAll('code');
</script><br />
Recently, I needed to change a basic enumeration into a full-fledged state pattern. After getting all my domain classes updated, I began reviewing the persistence layer. And I hit a wall.  I wasn’t sure how I wanted to update my Fluent NHibernate convention to persist the current state.</p>
<p>My original classes were similar to this:</p>
<pre class="brush: csharp;">public class MyProgress{
   public virtual Guid Id { get; set; }
   ...
   ...
   public virtual MyStatus Status { get; private set; }
}

public enum MyStatus{
   New,
   InProgress,
   Completed,
   Canceled,
   Failed
}
</pre>
<p>My new state pattern was similar to this:</p>
<pre class="brush: csharp;">
public abstract class MyStatus
{
    public static readonly MyStatus New = new NewStatus();
    public static readonly MyStatus InProgress = new InProgressStatus();
    ...
}

public class NewStatus: MyStatus
{
    public override void Start(MyProgress progress)
    {
        progress.SetStatus(InProgress);
    }
    public override void Cancel(MyProgress progress)
    {
        progress.SetStatus(Cancelled);
    }
    public override void Fail(MyProgress progress)
    {
            progress.SetStatus(Failed);
    }
}
...
</pre>
<p>Here is the problem… My enumeration was persisted as an integer field on the record. Now that I had a state pattern, how should I save my state? I googled the problem and found <a href="http://www.lostechies.com/blogs/derickbailey/archive/2008/11/26/mapping-a-state-pattern-with-nhibernate.aspx" target="_blank">Derick Bailey’s article</a> on the state pattern and Fluent NHibernate. Derick’s pattern works well, but I felt that creating a lookup table in my database just so I can persist a value in another table was not the path I wanted to traverse – I wasn’t persisting an entity, I was persisting a state value on an entity. Not finding any more love from Google, I asked around and was advised to contact fellow Elegant Coder and <a href="http://guild3.com" target="_blank">Guild3</a> member, <a href="http://elegantcode.com/author/jgrundy/" target="_blank">Jason Grundy</a>. Here is Jason’s advice:</p>
<blockquote><p>&#8220;I&#8217;ve recently changed from using Enums to an approach outlined by Jimmy Bogard <a href="http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/08/12/enumeration-classes.aspx">here</a>.  In the Entity I would do something like this:</p>
<pre class="brush: csharp;">
protected int _orderStatusId;
public virtual OrderStatus OrderStatus
{
    get { return Enumeration.FromValue&lt;OrderStatus&gt;(_orderStatusId); }
    set { _orderStatusId = value.Value; }
}
</pre>
<p>Then in Fluent NH you can simply map to the protected member.&#8221;</p></blockquote>
<p>I decided to pursue Jason’s advice.  The result is my database tables did not need to change at all. Here is some snippets of the updated classes:</p>
<pre class="brush: csharp;">
public class MyProgress
{
     public virtual Guid Id {get;set;}
     ...
     protected int _status;
     public virtual MyStatus
     {
         get{ return Enumeration.FromValue&lt;MyStatus&gt;(_status); }
         set{ _status = value.Value; }
     }
     ...
}

public class MyStatus : Enumeration
{
     public static MyStatus New = new NewStatus();
     ...

     private class NewStatus : MyStatus
    {
         public NewStatus() : base (0,"New"){}

         public override void Start(MyProgress progress)
         {
             progress.SetStatus(InProgress);
         }
    }
     ...
</pre>
<p>Notice that the MyStatus class is no longer abstract.  However, the subclasses are all private nested classes, each with a value and a display name.  I set each subclass value to match the enumeration value it replaced.  I did not need to convert my existing data to a new schema.</p>
<p>And here is the Fluent NHibernate override:</p>
<pre class="brush: csharp;">
public class MyProgressOverride : IAutoMappingOverride&lt;MyProgress&gt;
{
    public void Override(AutoMapping&lt;MyProgress&gt; mapping)
    {
        mapping.Map(x =&gt; x.Status)
            .CustomType(typeof(int))
            .Access.CamelCaseField(Prefix.Underscore);
    }
}
</pre>
<p>As you can see, we use convention-based automapping with overrides, but this same map could be used in a standard class map.</p>
<p>Thanks to Jimmy, Derick, and Jason for the inspiration and assistance!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=CkFGN6IntZk:86HBhpiZaMU:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=CkFGN6IntZk:86HBhpiZaMU:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=CkFGN6IntZk:86HBhpiZaMU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=CkFGN6IntZk:86HBhpiZaMU:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=CkFGN6IntZk:86HBhpiZaMU:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=CkFGN6IntZk:86HBhpiZaMU:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/CkFGN6IntZk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/01/state-pattern-enumeration-class-and-fluent-nhibernate-oh-my/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Snow Leopard and Quicksilver</title>
		<link>http://elegantcode.com/2009/11/01/snow-leopard-and-quicksilver/</link>
		<comments>http://elegantcode.com/2009/11/01/snow-leopard-and-quicksilver/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 21:46:54 +0000</pubDate>
		<dc:creator>Kirstin Juhl</dc:creator>
				<category><![CDATA[Esoterica]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Snow Leopard]]></category>

		<guid isPermaLink="false">http://elegantcode.com/?p=2828</guid>
		<description><![CDATA[I recently did the upgrade to Snow Leopard on my MBP. To my dismay, Quicksilver no longer worked. It terminated immediately after launch. 
I found the the Beta 56a7 on here. 
I also had to remove Plugins.plist and the Plugins folder from ~/Library/Application Support/Quicksilver. 
I am ecstatic to report that Quicksilver is up and running [...]]]></description>
			<content:encoded><![CDATA[<p>I recently did the upgrade to Snow Leopard on my MBP. To my dismay, Quicksilver no longer worked. It terminated immediately after launch. </p>
<p>I found the the Beta 56a7 on here. </p>
<p>I also had to remove Plugins.plist and the Plugins folder from ~/Library/Application Support/Quicksilver. </p>
<p>I am ecstatic to report that Quicksilver is up and running again, and my Mac is happy.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lYoOfIV9xaY:_14oWO4AT7A:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=lYoOfIV9xaY:_14oWO4AT7A:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lYoOfIV9xaY:_14oWO4AT7A:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lYoOfIV9xaY:_14oWO4AT7A:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lYoOfIV9xaY:_14oWO4AT7A:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=lYoOfIV9xaY:_14oWO4AT7A:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/lYoOfIV9xaY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/01/snow-leopard-and-quicksilver/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Book Review: Enterprise Service Bus</title>
		<link>http://elegantcode.com/2009/10/30/book-review-enterprise-service-bus/</link>
		<comments>http://elegantcode.com/2009/10/30/book-review-enterprise-service-bus/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 20:59:34 +0000</pubDate>
		<dc:creator>Jan Van Ryswyck</dc:creator>
				<category><![CDATA[Books]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/10/30/book-review-enterprise-service-bus/</guid>
		<description><![CDATA[ About a year ago, I was lucky enough to attend the Kaizenconf in Austin. When I joined the discussions on ESB Patterns, Dru Sellers and Chris Patterson (also known as the MassTransit guys) were talking about this book called Enterprise Service Bus from David Chappell. I finally took the time to read it and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://elegantcode.com/wp-content/uploads/2009/10/ESB.jpg"><img style="border-bottom: 0px; border-left: 0px; border-top: 0px; border-right: 0px" border="0" alt="ESB" align="left" src="http://elegantcode.com/wp-content/uploads/2009/10/ESB_thumb.jpg" width="214" height="281"></a> About a year ago, I was lucky enough to attend the Kaizenconf in Austin. When I joined the discussions on <a href="http://kaizenconf.pbworks.com/ESB-Patterns" target="_blank">ESB Patterns</a>, <a href="http://codebetter.com/blogs/dru.sellers/default.aspx" target="_blank">Dru Sellers</a> and <a href="http://www.lostechies.com/blogs/chris_patterson/default.aspx" target="_blank">Chris Patterson</a> (also known as the MassTransit guys) were talking about this book called <a href="http://www.amazon.com/exec/obidos/ASIN/0596006756/elegantcode-20" target="_blank">Enterprise Service Bus</a> from <a href="http://www.oreillynet.com/pub/au/207" target="_blank">David Chappell</a>. I finally took the time to read it and for the most part it was a real eye opener. As you might have guessed, the book provides an architectural overview of the ESB concept. Although it does provide some amount of detail, there are no in depth discussions on any particular technologies. But after reading the book it is quite clear that the author comes more from a Java background. However this is not that important for a book like this as these concepts are technology agnostic anyway. </p>
<p>I must admit that getting through the first chapter, which tries to introduce the ESB, was not that easy. Too abstract and high level for my taste. </p>
<p>The second chapter is about the <em>State of Integration</em> and discusses how both business and technical drivers contributed to the ESB approach as opposed to Enterprise Application Integration (EAI). One of the best parts in the book is the discussion about &#8220;Accidental Architecture&#8221; which is an accurate and far too familiar description of the current architecture in most companies. Although the book is approximately 5 years old, it is still very relevant as the adoption rate of ESB&#8217;s is still not that common. But then again, I could be wrong about this <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .&nbsp;&nbsp;&nbsp; </p>
<p>The third chapter examines the key concepts of an ESB were the author tries to prove that these are born out of necessity, based on real requirements and problems that couldn&#8217;t be solved with typical EAI broker architectures (like Biztalk for example).</p>
<p>Chapter 4 states that XML is the exchange format of choice for passing data structures between applications and services. Nothing new here.</p>
<p>Chapter 5 till 8 provide in dept information about each of the key concepts described in chapter 4, like Message Oriented Middleware (MOM), Service Containers and Endpoints, Routing, Transformation, Messaging, etc. &#8230;</p>
<p>Chapter 9 goes back to the real world by exploring the most common form of integration that is practiced today: bulk data transfer using ETL and an endless amount of small batch applications. Sounds familiar? This chapter also provides the necessary steps in order to migrate away from latency and reliability issues towards a real-time integration and how this affects your business.</p>
<p>Chapter 10 is a bit more technology focused as it talks about Java Components in an ESB. However, this could equally be .NET or any other platform.</p>
<p>For me, chapter 11 is a real masterpiece especially the part on Portal Server Integration patterns like Forward Cache and Federated Query. Highly recommended reading. </p>
<p>The final chapter discusses the WS-DeathStar (WS-*) specifications and what they could mean for an ESB.</p>
<p>In the end, I have a lot to think about after reading this book. It challenged a lot of my earlier assumptions on distributed computing and it certainly helped me understand a couple of things while I was <a href="http://elegantcode.com/2009/10/09/exploring-nservicebus/" target="_blank">exploring NServiceBus</a>.</p>
<p>Till next time</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=A9WfCTxFBTI:r4X99hUeNz4:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=A9WfCTxFBTI:r4X99hUeNz4:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=A9WfCTxFBTI:r4X99hUeNz4:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=A9WfCTxFBTI:r4X99hUeNz4:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=A9WfCTxFBTI:r4X99hUeNz4:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=A9WfCTxFBTI:r4X99hUeNz4:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/A9WfCTxFBTI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/10/30/book-review-enterprise-service-bus/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Cast 33 – Jimmy Bogard on AutoMapper</title>
		<link>http://elegantcode.com/2009/10/29/code-cast-33-jimmy-bogard-on-automapper/</link>
		<comments>http://elegantcode.com/2009/10/29/code-cast-33-jimmy-bogard-on-automapper/#comments</comments>
		<pubDate>Fri, 30 Oct 2009 05:24:32 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[AutoMapper]]></category>
		<category><![CDATA[CodeCast]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/10/29/code-cast-33-jimmy-bogard-on-automapper/</guid>
		<description><![CDATA[AutoMapper is one those tools tools that seems to be gaining in popularity lately, generating a lot of talk on the web and at user groups.&#160; Seemed like a good idea to talk with its creator, Jimmy Bogard, and get the run-down on it.
In this code case we have Elegant Coders Chris Brandsma and Richard [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.codeplex.com/AutoMapper">AutoMapper</a> is one those tools tools that seems to be gaining in popularity lately, generating a lot of talk on the web and at user groups.&#160; Seemed like a good idea to talk with its creator, <a href="http://www.lostechies.com/blogs/jimmy_bogard/">Jimmy Bogard</a>, and get the run-down on it.</p>
<p>In this code case we have Elegant Coders <a href="http://elegantcode.com/about/chris-brandsma/">Chris Brandsma</a> and <a href="http://elegantcode.com/about/richard-cirerol/">Richard Cirerol</a> (listen as Chris completely stumbles over Rich’s last name), and we are joined by Cory Isakson.&#160; For those of you outside of Bosie, Cory is a local usergroup leader, Code Camp presenter, and .net junky.&#160; We keep trying to get Cory to blog, but so far he is resisting our calls.</p>
<ul>
<li><a href="http://www.lostechies.com/blogs/jimmy_bogard/">Jimmy’s Blog</a></li>
<li><a href="http://www.codeplex.com/AutoMapper">AutoMapper</a></li>
<li><a href="http://structuremap.sourceforge.net/Default.htm">StructureMap</a></li>
</ul>
<p><a href="http://pluralsight-elegant.s3.amazonaws.com/ECC_33_JimmyBogard.mp3">Get the show here</a></p>
<p><a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=271207118"><img border="0" alt="View in iTunes" src="http://elegantcode.com/cast/files/images/itunes_button.gif" /></a> <a href="http://feeds2.feedburner.com/elegantcodecast"><img border="0" alt="Any Podcatcher" src="http://elegantcode.com/cast/files/images/rss_podcast.jpg" /></a></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=czJKO5BD8hI:UUkqWMMhly0:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=czJKO5BD8hI:UUkqWMMhly0:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=czJKO5BD8hI:UUkqWMMhly0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=czJKO5BD8hI:UUkqWMMhly0:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=czJKO5BD8hI:UUkqWMMhly0:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=czJKO5BD8hI:UUkqWMMhly0:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/czJKO5BD8hI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/10/29/code-cast-33-jimmy-bogard-on-automapper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://pluralsight-elegant.s3.amazonaws.com/ECC_33_JimmyBogard.mp3" length="36496077" type="audio/mpeg" />
		</item>
		<item>
		<title>Next European VAN on 18 November 2009</title>
		<link>http://elegantcode.com/2009/10/29/next-european-van-on-18-november-2009/</link>
		<comments>http://elegantcode.com/2009/10/29/next-european-van-on-18-november-2009/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 20:45:48 +0000</pubDate>
		<dc:creator>Jan Van Ryswyck</dc:creator>
				<category><![CDATA[E-VAN]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/10/29/next-european-van-on-18-november-2009/</guid>
		<description><![CDATA[Mark Nijhof is going to enlighten us all with his DDD/CQRS sample application. You can read all about it at the E-VAN blog.
]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.fohjin.com/" target="_blank">Mark Nijhof</a> is going to enlighten us all with his DDD/CQRS sample application. You can read all about it at the <a href="http://europevan.blogspot.com/2009/10/next-european-van-on-18-november-2009.html" target="_blank">E-VAN blog</a>.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=LFsMfU85XvA:ylHszWXxIZg:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=LFsMfU85XvA:ylHszWXxIZg:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=LFsMfU85XvA:ylHszWXxIZg:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=LFsMfU85XvA:ylHszWXxIZg:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=LFsMfU85XvA:ylHszWXxIZg:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=LFsMfU85XvA:ylHszWXxIZg:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/LFsMfU85XvA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/10/29/next-european-van-on-18-november-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Software, Sewing, and the Craftsman</title>
		<link>http://elegantcode.com/2009/10/29/on-software-sewing-and-the-craftsman/</link>
		<comments>http://elegantcode.com/2009/10/29/on-software-sewing-and-the-craftsman/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 20:23:09 +0000</pubDate>
		<dc:creator>David Starr</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[Craftsmanship]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/10/29/on-software-sewing-and-the-craftsman/</guid>
		<description><![CDATA[My wife, Eleanor, runs a small side business making some extraordinary things with needles, thread, and cloth. She makes quilts, dresses, stuffed animals, clothes, and reupholsters furniture to round it off. She’s been honing her skills, trying new things, and improving her craftsmanship for many years. She’s very good and has some faithful clients. 
Recently, [...]]]></description>
			<content:encoded><![CDATA[<p>My wife, Eleanor, runs a small side business making some extraordinary things with needles, thread, and cloth. She makes quilts, dresses, stuffed animals, clothes, and reupholsters furniture to round it off. She’s been honing her skills, trying new things, and improving her craftsmanship for many years. She’s very good and has some faithful clients. </p>
<p>Recently, it occurred to me to ask her a seemingly innocuous question:</p>
<blockquote><p>When a client asks you to make something you’ve never made before, what do you tell them it will cost?</p>
</blockquote>
<p>“First of all,” she replied, “every single job is something I’ve never done before.”</p>
<p>Boom. I think we’re on familiar ground here.</p>
<p>I wrote some questions for her to answer in an email and this post shows her responses. Her answers appear in italics. </p>
<p>I find this a fascinating discussion of project estimation and craftsmanship.</p>
<h3>What do you do when the client doesn’t know what they want?</h3>
<p><em>There are two kinds of clients that fit into that category:&#160; </em></p>
<ol>
<li><em>Those who have some sort of unqualified vision and hazy idea of what they want, but lack the vocabulary and expertise to complete their thoughts</em></li>
<li><em>Those who want something different from what they have, and don&#8217;t really care much beyond that.</em></li>
</ol>
<p><em>Customer&#160; #1 is the most work of the two.&#160; They deserve and require time, since they are paying me for my services.&#160; It takes time sitting with these clients, talking through concepts, drawing things on paper, asking questions and offering ideas trying to get to the core of what they want, what they actually need and what&#8217;s physically possible.&#160; I have found that it takes a high level of skill to create something that is perfect to someone else.</em></p>
<p><em>Customer # 2 doesn&#8217;t happen often, but is a lot of fun!&#160; These are the rare clients that enable my inner artist to flourish and shine, with no constraints or outside demands.&#160; These are the clients want something new and shiny, but don&#8217;t have a huge list of demands. They want some sort of element of surprise.&#160; </em></p>
<p><em>Problems ensue when I think I&#8217;ve got a #2 and didn&#8217;t ask enough question to realize I was dealing with a #1.&#160; </em></p>
<h3>How do you charge your clients?</h3>
<p><em>Certain jobs have a set fee.&#160; These are tasks I&#8217;ve done for 20 years; I know how long they take, I could do them in my sleep, and they&#8217;re the same regardless of the client.&#160; On the incredibly rare occasion one of these jobs isn&#8217;t what it appeared to be, my bad and I eat the cost (and I&#8217;ll pay more attention next time!).</em></p>
<p><em>Other jobs, the custom jobs, are harder to price out.&#160; Now that I have a larger body of work, I have a better idea of how long things take.&#160; If it&#8217;s something I&#8217;ve never done, I estimate my time in my head, and then (because I&#8217;m always overly optimistic in my estimation) I double that to come up with my estimated total of time.&#160; Then I factor in&#160; what my time is worth per hour.&#160; </em></p>
<p><em>I also have to know what other professionals are charging for similar services, as it&#8217;s tough to get clients if I&#8217;m charging twice what everyone else wants for the same service.</em></p>
<h3>Do you tell them up front what a job will cost?</h3>
<p><em>If it&#8217;s not a custom job, I always tell my clients the cost up front.&#160; I may adjust the cost of a task between clients, but I don&#8217;t change the price after I&#8217;ve quoted on non-custom jobs.</em></p>
<p><em>Pricing custom jobs is a lot harder.&#160; I run my formula:&#160; estimated time, doubled, multiplied by an hourly rate.&#160; And I offer that as an estimate.&#160; I explain to my customer that it is an estimate to the best of my abilities, and that the price could fluctuate up or down.&#160; I&#8217;ve learned that I don&#8217;t want the clients who aren&#8217;t willing to work within this structure;&#160; these tend to be the people who really, really want custom work and really, really don&#8217;t want to pay custom prices.</em></p>
<h3>What do you do when it takes longer than you thought?</h3>
<p><em>I&#8217;ve found that the bigger the project, the more willing the customer is to accommodate&#160; an extended deadline.&#160; At the first sign of missing a deadline, I call the customer. It helps a lot, at this point, to be able to show my customer what I have actually accomplish already. </em></p>
<p><em>Also, if it&#8217;s something I&#8217;ve never done before, I tell the client that I&#8217;ve never done a job exactly like that one, and my time estimate is only an estimate.</em></p>
<h3>On a long or complex project, when do you consult with the client to guide your decisions?</h3>
<p><em>If it&#8217;s a client #2, I don&#8217;t usually consult with them once I&#8217;ve started the project.&#160; If I&#8217;ve come to a point where things veer wildly in opposite directions, I may have the client stop by to choose option A or B.&#160; Usually, with customer #2, I do it how I want to do it.</em></p>
<p><em>Custom jobs for a client #1 elicit a lot of phone calls.&#160; I like to check with the customer at each phase when I&#8217;m not completely sure what they&#8217;d choose;&#160; a 2 minute phone call takes a lot less time than picking 150 staples out of someone&#8217;s wingback chair.&#160; I have never had a customer be irritated with me for making sure I was meeting their needs.</em></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ABeBqpX_jIU:jiKUWH2Bs7M:V_sGLiPBpWU"><img src="http://feeds.feedburner.com/~ff/ElegantCode?i=ABeBqpX_jIU:jiKUWH2Bs7M:V_sGLiPBpWU" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ABeBqpX_jIU:jiKUWH2Bs7M:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ABeBqpX_jIU:jiKUWH2Bs7M:7Q72WNTAKBA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=7Q72WNTAKBA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ABeBqpX_jIU:jiKUWH2Bs7M:XAVGb8Xj5zA"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=XAVGb8Xj5zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/ElegantCode?a=ABeBqpX_jIU:jiKUWH2Bs7M:G79ilh31hkQ"><img src="http://feeds.feedburner.com/~ff/ElegantCode?d=G79ilh31hkQ" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/ElegantCode/~4/ABeBqpX_jIU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/10/29/on-software-sewing-and-the-craftsman/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
