<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Elegant Code &#187; Chris Brandsma</title>
	<atom:link href="http://elegantcode.com/author/brandsma/feed/" rel="self" type="application/rss+xml" />
	<link>http://elegantcode.com</link>
	<description></description>
	<lastBuildDate>Tue, 20 Jul 2010 12:52:47 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Asp.Net MVC: My Personal View Rules</title>
		<link>http://elegantcode.com/2010/07/05/asp-net-mvc-my-personal-view-rules/</link>
		<comments>http://elegantcode.com/2010/07/05/asp-net-mvc-my-personal-view-rules/#comments</comments>
		<pubDate>Mon, 05 Jul 2010 23:10:02 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>

		<guid isPermaLink="false">http://elegantcode.com/?p=3641</guid>
		<description><![CDATA[I&#8217;ve been working with a team of guys on several Asp.Net MVC projects since October of 2009.  While that isn&#8217;t the greatest amount of time, and I&#8217;m still no expert, I thought I&#8217;d jot down a few of the practices that we have developed to help make coding a bit smoother.  Asp.Net MVC, as with [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working with a team of guys on several Asp.Net MVC projects since October of 2009.  While that isn&#8217;t the greatest amount of time, and I&#8217;m still no expert, I thought I&#8217;d jot down a few of the practices that we have developed to help make coding a bit smoother.  Asp.Net MVC, as with every new technology can be used poorly, and when use poorly you try to identify why that code was bad, how it could have been done better.</p>
<p>First, lets think about what the view should be doing &#8211; in a single responsibility sort of way: turn data into html.  That right there rules out several options.  No retrieving data, no extra data transformations.  Just turn some data into html.  And frankly, that is complicated enough.  So a side goal that I strive for is to create a markup page (the aspx) that is similar to the desired html output.  The main reason for that side goal is to make double checking the output that much easier.  I want to see a &#8216;div&#8217; in my markup, and have a reasonable idea where that &#8216;div&#8217; will show up in the html.</p>
<ol>
<li><strong>Keep as much code out of your views as you can.</strong></li>
</ol>
<p>Don&#8217;t make this rule overly simplistic.  Some code belongs in the view.  A &#8216;for&#8217; loop to create a table, a simple &#8216;if&#8217; block to show administrator functionality, stuff like that.  But you shouldn&#8217;t be having to specify the DateTime format, or string parsing.  That is what the ViewModels should do for you.  Rule of thumb, if you see a block where there is more C# than HTML, you probably did it wrong.</p>
<p>I will also extend this rule to JavaScript as well.  I&#8217;ve talked about the why JavaScript should not be in the views before, so this should not be a shock.  JavaScript belong in separate files.  Period.</p>
<p>2. <strong>Make Views typed.</strong></p>
<p>This is true for all views where you have to pass data from the controller to the view.  Make a View Model for the view and pass data via that model.  This opens up a whole host of better patterns for you, like typed HtmlHelpers.  As a result, it is VERY rare that I will share a view model between views, or even Controller Actions.  I make separate models for GET, POST, and DELETE.  I guess my view is, the more the merrier.</p>
<p>3.   <strong>Make the View Models specific to the needs of the view.</strong></p>
<p>OK, this isn&#8217;t actually a View best practice, but it is highly related.  If you try to keep the model for the view too generic, you end up with a lot of logic in the view to transpose the data into something useful.  The key point is that the data in the model serves the view, so all of the work to get the data into the correct format should be done when putting the data into  the model.  I will often take this to the point where the model will give html elements in the view their CSS classes.  So that means I have more than data from the database in the views.</p>
<p>Side note: when it comes to populating View Models with data specific for the View, <a href="http://automapper.codeplex.com/">AutoMapper</a> rocks!  That is all.</p>
<p>4.  <strong>Custom Html Helpers are wonderful things</strong></p>
<p>It is remarkably simple to create your own Html Helper, and once you get the hang of them they are beautiful.  They are wonderful little ways to encapsulate a small amount of logic so you can get it out of the aspx view.  Use them to encapsulate small amounts of code you need in various place through the project.</p>
<p>Another little &#8220;trick&#8221; I will use from time to time to create custom models just for a html helper (passed in via the view&#8217;s view model).  I have a few places where I need to change the markup because of the browser being used&#8230;so I create a custom helper that can detect the browser.</p>
<p>5. <strong>Standard HTML Helpers are great, but remember html</strong></p>
<p>The key point I&#8217;m trying to make here is to become familiar with the output of the standard HTML helpers.  While the helpers can be great, they have their warts (anything having to do with an attribute name/value is a bit ugly).  Sometimes it is easier to swap them out with the standard html (especially with inputs) to get the exact output you want.  As a bonus, it is easier for the next guy coming in to figure out what you were after.   Currently, I&#8217;d say I use the helpers about 50% of the time over raw HTML.</p>
<p>Now, typing the html, or the helper, still kind of stinks.  You have to type the same code over and over.  Take a look at what <a href="http://code.google.com/p/zen-coding/">Zen-Coding</a> does.  You can do the same thing with ReSharper Templates or Visual Studio snippets&#8230;or just install one of the ReSharper or Visual Studio pluggins.  But beyond that, there is an art to customizing Visual Studio that you should learn.</p>
<p>6. <strong> Wrap all links in Url.Content and Url.Action</strong></p>
<p>You have a web app.  You have to navigate between pages, call web services, link in javascript and CSS.  That is just what we do.  All of those links should be wrapped in Url.Content or Url.Action helpers.   The problem that is easy to run into is you move from development to test and the base url for your application changes.  You were testing at http://localhost:898989/ , and now you are deployed to http://myserver/myapp/  and a whole lot of urls just stopped working.  Url.Content and Url.Action are supposed to fix that.  That is why you use them.</p>
<p>7.  <strong>Get to know Partial Views for Ajax calls.</strong></p>
<p>Partial views are actually just views that don&#8217;t have master pages and the html/body tag sections.  Partials can be executed in a multitude of ways, not just from inside a view on the server, but also from Javascript on the browser. JQuery also has a wonderful little method called $.load that will call a url, take the html that is returned, and slap it into the page.  This can greatly simplify a lot of behaviors.</p>
<p>I subtle little trick I sometimes do with this this is to wrap a section of code that takes a long time to load in a partial.  I will then call that partial into my page AFTER is has loaded on the browser (using the JavaScript function setTimeout to call the $.load ).  Now I get  a page that loads faster, but still has all of the data it needs.</p>
<p>8. <strong>Make the Master page work for you.</strong></p>
<p>It isn&#8217;t that there is something inherently wrong with the existing master page that you get when you create a new Asp.net MVC project.  Typically it is 80% of what you would want.  But, as soon as I know what my general page is supposed to look like, I rip right into the Master Page.   Also keep in mind that you can nest Master Pages as well.</p>
<p>9. <strong>Think about what a designer would want.</strong></p>
<p>Even if you don&#8217;t have one.  This is just a general pattern I try to get into.  I think about a designer as someone that can take raw html, add some css and images and make my work look a LOT better.    This means I use the raw html whenever possible, I write my JavaScript click handler so they will work with buttons or links (hint: always return false &#8212; and why haven&#8217;t I written a JQuery plugin for this yet?).</p>
<p>10.  <strong>Version your css and JavaScript</strong></p>
<p>This is actually getting into my next blog post, but figure out a way to version your JavaScript and CSS.  This really isn&#8217;t MVC specific, you should do this in almost any project.  The key reason is to help you with a browser&#8217;s cache.  You know you have a problem when the first thing someone tells you, when asking for help, is that they cleared their cache already.   My thought on this is your web app&#8217;s dll should have a version number, set the project to auto version, and then pop that onto the end of the css/javascript file call.  So it might look like this:  &#8221;http://myapp/&#8230;/file.css?version=1.0.0.256&#8243;.   In my sample code, when in development I stick a timestamp on the file in the same way.</p>
<p>OK, 10 rules is quite enough (I didn&#8217;t even think I would get that many).   To the american&#8217;s reading this: Happy Independence Day.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/07/05/asp-net-mvc-my-personal-view-rules/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Developers still need database skills</title>
		<link>http://elegantcode.com/2010/04/30/developers-still-need-database-skills/</link>
		<comments>http://elegantcode.com/2010/04/30/developers-still-need-database-skills/#comments</comments>
		<pubDate>Sat, 01 May 2010 00:53:37 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/04/30/developers-still-need-database-skills/</guid>
		<description><![CDATA[Rant here.&#160; First off, I’m going to be talking about DBAs.&#160; And by DBA, I mean a database developer.&#160; Someone who knows relational theory, optimization, and SQL inside out.&#160; This is an R&#38;D DBA.&#160; There is another type of DBA that mainly deals with uptime and backup strategies.&#160; This is an IT DBA, I’m not [...]]]></description>
			<content:encoded><![CDATA[<p>Rant here.&#160; First off, I’m going to be talking about DBAs.&#160; And by DBA, I mean a database developer.&#160; Someone who knows relational theory, optimization, and SQL inside out.&#160; This is an R&amp;D DBA.&#160; There is another type of DBA that mainly deals with uptime and backup strategies.&#160; This is an IT DBA, I’m not talking about that one at all.</p>
<p>I was going to talk to some of my fellow developers about a couple of database issues.&#160; The response was, “you said the ‘D’ word.&#160; Now, we are an NHibernate/Microsoft SQL Server shop (or, Fluent NHibernate), and we rarely have to think about think about database architecture.&#160; Heck, up till a month ago I don’t think we had to do any native SQL queries at all.&#160; Currently, I don’t think we have any stored procs at all.&#160; In my book, all of that is a good thing.&#160; You can also chalk one up to Microsoft SQL Server in this one, our system has grown a lot and performance has remained pretty darn stable.</p>
<p>And lets be frank, I love this – most of the time.&#160; Linq To NHibernate queries, Fluent NHibernate, and the like all make for a very enjoyable experience for developing against a database.&#160; I would say that the vast majority of our querying needs are met with no further issues.&#160; I certainly don’t want to go back to a stored proc world.&#160; </p>
<p>That said, I don’t like using our ORM as an excuse to not talk about database issues or SQL issues.&#160; If you are using a particular data storage technology, it still behooves you to know as much about it as possible.&#160; Otherwise, when you get to a point where you need to know about what is going on will be too late.&#160; Lets be frank here, no ORM will handle all of you query needs.&#160; At best we are talking 90%, sometimes only 80%, for a typical application.&#160; At some point you either have to go to the metal, or you end up coding things in a very strange way.</p>
<p>So here is the main point, as long as Relational Databases continue to be the “right answer” for business data storage, you need to learn database theory and SQL.&#160; You might not need to know SQL as well as your native C#, Ruby, or other main language.&#160; But that is not an excuse for not being comfortable with left outer joins, third normal form, and indexing.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/04/30/developers-still-need-database-skills/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Your JavaScript goes WHERE?</title>
		<link>http://elegantcode.com/2010/03/30/your-javascript-goes-where/</link>
		<comments>http://elegantcode.com/2010/03/30/your-javascript-goes-where/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 03:35:37 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/03/30/your-javascript-goes-where/</guid>
		<description><![CDATA[Let me start by saying that I was not trying to be controversial.  I was at Boise Code Camp giving a session about Asp.Net MVC, and I happened to mention that JavaScript was supposed to go at the bottom of your page.  Plus, I said this in a “of course you all know this already” [...]]]></description>
			<content:encoded><![CDATA[<p>Let me start by saying that I was not trying to be controversial.  I was at Boise Code Camp giving a session about Asp.Net MVC, and I happened to mention that JavaScript was supposed to go at the bottom of your page.  Plus, I said this in a “of course you all know this already” type of voice, thinking this needed no further explanation.</p>
<p>Then the hands started raising.  Quickly, I might add.  I had to explain myself.  Yes, JavaScript goes at the bottom of your page.  Yes, I realize that we were all taught, back in the day, that JavaScript’s true home was in the &lt;head&gt; element.  In fact, <a href="http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery">many sample pages still show JavaScript at the top</a>.  But we probably learned that ten years ago, you have to think a few things have changed…except IE6 – that sucker is going to live forever!  Anyway, I’m not the type that like to stand up in a crowd and say “everything you, and everyone you know, is doing is wrong” (I’m not that smart).  And if I do, I want to come with some substantial proof.</p>
<p>To start, <a href="http://www.w3.org/TR/REC-html40/interact/scripts.html#h-18.2.1">where does the w3c say the SCRIPT element is supposed to go?</a>  If you read the document in the link, SCRIPT can live in either the HEAD or the BODY elements. So technically, both places are legal.  I am stating this so that no one come back and tells me I’m breaking any fundamental web rules.  If the w3c says it is ok, then it is ok darn it.</p>
<h2>But why the bottom of the page? </h2>
<p>That one is slightly harder to explain.  But here are the basics:  when a browser loads a document there are only so many thread for processing the document and download all the other crap that you put on the page <a href="http://theoatmeal.com/comics/design_hell">so it pops</a> (so, images and css, not to mention the bagillion font tags that Word likes to put in html).  There is also an unwritten rule that JavaScript should enhance the page after it is loaded.  So any time the browser spends parsing JavaScript is time it could be using to make the page look right.  Also, with some browsers, when the browser is loading JavaScript, ALL OTHER ACTIVITY STOPS.  Nothing else is downloaded, the browser is at a standstill until all the script is parsed – and <a href="http://ejohn.org/blog/javascript-performance-rundown/">you know how fast IE is at JavaScript.</a></p>
<p>Lets be clear about this “rule”.  <a href="http://developer.yahoo.com/performance/rules.html#js_bottom">I did not make this up.</a>  But there are other ways around the performance penalty, you can also <a href="http://code.google.com/speed/page-speed/docs/payload.html#DeferLoadingJS">defer load</a> your JavaScript.  Also, putting all of the JavaScript into a single, external file is a great idea.  With a external file you get the added benefit of the JavaScript file being cached by the browser (Note: great for the user – pain for your tester.  Repeat after me, “CLEAR YOUR CACHE” often when testing).</p>
<p>OK, so let us review.</p>
<p><a href="http://elegantcode.com/wp-content/uploads/2010/03/image17.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" src="http://elegantcode.com/wp-content/uploads/2010/03/image_thumb17.png" border="0" alt="image" width="823" height="594" /></a></p>
<h2>But how bad is this?</h2>
<p>That is a fair question as well.  Truthfully, it depends.  I know that is my stock answer, but I’m talking about how much this will affect the user.  It could be nothing.  But if you have a lot of JavaScript on the page, it could be significant.   Potentially it could be as annoying as a blink tag.  Even worse it might be on par with ESPN and their auto-playing videos.   But, if we are talking about 10-20 lines of script, there could be no change at all in render time. I will say this, by moving the script to the bottom of the page I have taken pages that were not usable for 10 seconds, improved it to moments (the page had a LOT of JavaScript…and it was a very noble cause).</p>
<h2>What else should I be doing that I’m not?</h2>
<p>This one is easy.  Run all of your pages through <a href="http://developer.yahoo.com/yslow/">YSlow</a> and <a href="http://code.google.com/speed/page-speed/">PageSpeed</a> (you need FireFox and <a href="http://getfirebug.com/">Firebug</a> installed for this) and find out.  Also, you don’t have to be perfect as far as these tools are concerned.  Some of the rule are probably not practical either (the “You should be using a CDN for images” rule comes to mind).  But it is good to know where you can improve.  PageSpeed has a number of really nice tools as well.  It will return you properly sized images, and compressed CSS and JavaScript if you ask it.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/03/30/your-javascript-goes-where/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Asp.Net MVC 2 Areas</title>
		<link>http://elegantcode.com/2010/03/13/asp-net-mvc-2-areas/</link>
		<comments>http://elegantcode.com/2010/03/13/asp-net-mvc-2-areas/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 00:13:19 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/03/13/asp-net-mvc-2-areas/</guid>
		<description><![CDATA[I’m looking into the new stuff in Asp.Net MVC 2, trying to figure out what is cool and what is just there.&#160; Areas look like a nice addition.&#160; Areas allow you to separate your Asp.Net MVC application into more distinct partitions.&#160; So all of the Controllers, Models, Views, and even routes belong to one directory [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://elegantcode.com/wp-content/uploads/2010/03/image13.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="image" border="0" alt="image" align="right" src="http://elegantcode.com/wp-content/uploads/2010/03/image_thumb13.png" width="119" height="244" /></a>I’m looking into the new stuff in Asp.Net MVC 2, trying to figure out what is cool and what is just there.&#160; Areas look like a nice addition.&#160; Areas allow you to separate your Asp.Net MVC application into more distinct partitions.&#160; So all of the Controllers, Models, Views, and even routes belong to one directory structure.&#160; It is like having a sub-project inside of you MVC project. </p>
<p>Here is the problem, as I see it:&#160; as an MVC project gets large, keeping all of the necessary pieces and parts for a set of controller actions straight can get a bit daunting.&#160; I’ve ended up with duplicate folder structures in views and models, which can make navigation a pain.</p>
<p>To make a new Area, simply right-click anywhere in you MVC project, Add-&gt;Area.&#160; As I said, you can do this from anywhere in the project structure, but the Areas are created in a new “Areas” folder.&#160; When you name the Area, a new folder is created with the Areas name as well.</p>
<p>Once created you should see all the familiar Controllers, Models, and Views folders (all blank).&#160; In addition to that, you will see an &lt;name&gt;AreaRegistration.cs file.&#160; This inherits from AreaRegistration, and this is where any new Routes go.&#160; In the file is a prebuilt route that should look similar to this:</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> context.MapRoute(</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: #006080">&quot;test1_default&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: 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: #006080">&quot;test1/{controller}/{action}/{id}&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="lnum4">   4:</span>     <span style="color: #0000ff">new</span> { action = <span style="color: #006080">&quot;Index&quot;</span>, id = UrlParameter.Optional }</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> );</pre>
<p><!--CRLF--></div>
</div>
<p>So a url to the area would include /test1/ (name of my Area) in the path.&#160; That would be good if you had multiple controllers with the same name, but if you don’t, just take out the “test1” and you won’t need it in the path.</p>
<p>Also, if you leave Area name in the route, you will have a little more work to, here is what one of mine looked like:&#160; &lt;%=Html.ActionLink(&quot;test&quot;, &quot;Index&quot;, &quot;test1/TestArea&quot;) %&gt;.&#160; But it turns out this is more correct: </p>
<p>&lt;%=Html.ActionLink(&quot;test&quot;, &quot;Index&quot;, &quot;TestArea&quot;, new { area=&quot;Test1&quot;}, new {}) %&gt; </p>
<p>This also mean that any controller actions you want to link to outside if Area needs to include a blank area in the link, like this:</p>
<p>&lt;%=Html.ActionLink(&quot;Home&quot;, &quot;Index&quot;, &quot;Home&quot;, new { area=&quot;&quot;}, new {}) %&gt; </p>
</p>
<p>In case you are wondering, the first object in the area is for route values, the second is for html attributes.</p>
<p>So the downside of using Areas is that you could complicate your routing in a hurry.&#160; Plus it does not look like the Html helpers are there to lend you a hand either.&#160; It is very doable, just annoying.&#160; Of course, the easy fix is to remove the Area name from the route and move on.&#160; That should be ok so long as you do not have two controllers with the same name.</p>
<p>So are Areas a compelling feature? I think so.&#160; Plus, the larger the site, the more compelling Areas can become.&#160; For smaller sites, probably not.&#160; But I would not say no either.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/03/13/asp-net-mvc-2-areas/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>JQuery Validator Cheat Sheet</title>
		<link>http://elegantcode.com/2010/03/02/jquery-validator-cheat-sheet/</link>
		<comments>http://elegantcode.com/2010/03/02/jquery-validator-cheat-sheet/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 21:56:18 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://elegantcode.com/?p=3313</guid>
		<description><![CDATA[I’m getting a session ready for Boise Code Camp 2010 on JQuery Validator.  I thought it would be cool to hand out a cheat sheet – but I couldn’t find one.  So here is rev. 1 of my Jquery Validator Cheat sheet.
]]></description>
			<content:encoded><![CDATA[<p>I’m getting a session ready for <a href="http://BoiseCodeCamp.com">Boise Code Camp 2010</a> on <a href="http://docs.jquery.com/Plugins/Validation">JQuery Validator</a>.  I thought it would be cool to hand out a cheat sheet – but I couldn’t find one.  So here is rev. 1 of my <a href="http://elegantcode.com/wp-content/uploads/2010/03/Jquery-Validator-Cheat-sheet.pdf">Jquery Validator Cheat sheet</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/03/02/jquery-validator-cheat-sheet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Note to self: Asp.Net MVC Controllers are not Code Behind</title>
		<link>http://elegantcode.com/2010/02/23/note-to-self-asp-net-mvc-controllers-are-not-code-behind/</link>
		<comments>http://elegantcode.com/2010/02/23/note-to-self-asp-net-mvc-controllers-are-not-code-behind/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 22:28:27 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/02/23/note-to-self-asp-net-mvc-controllers-are-not-code-behind/</guid>
		<description><![CDATA[Sometimes I think things are more complicated than they really are.&#160; I got my head into a bind recently when I had some code that I really wanted under test in a Controller Action.
My first thought was “Crap, this is going to be rough”.&#160; Mainly I was still thinking of my time trying to test [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes I think things are more complicated than they really are.&#160; I got my head into a bind recently when I had some code that I really wanted under test in a Controller Action.</p>
<p>My first thought was “Crap, this is going to be rough”.&#160; Mainly I was still thinking of my time trying to test Code Behind in Asp.Net WebForms.&#160; I had to smack myself a few times after I remembered that the Controller base class is an abstract type.&#160; Reality is that a Controller doesn’t have to be any harder to test than any other service class.&#160; It isn’t like inheriting from Page (Asp.Net WebForms).</p>
<p>Not that my code did not have some lingering issues.&#160; Like: why did I have something in my Controller Action that would require testing in the first place?&#160; I hate having much logic at all in my Actions.&#160; Get input, send it off for processing (logic), go somewhere.&#160;&#160; That should be about it – unless you have to go to different places depending on what is returned.&#160; Now, I want some tests.</p>
<p>Anyway, now back to your regularly scheduled program.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/02/23/note-to-self-asp-net-mvc-controllers-are-not-code-behind/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extend your Master Pages</title>
		<link>http://elegantcode.com/2010/02/18/extend-your-master-pages/</link>
		<comments>http://elegantcode.com/2010/02/18/extend-your-master-pages/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 21:29:07 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[.Net 3.5]]></category>
		<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/02/18/extend-your-master-pages/</guid>
		<description><![CDATA[This is an idea that I’ve been throwing around for a while now, and I have implemented in a couple of project.&#160; The basic idea is to extend the basic master page, by adding more ContentPlaceholders, to give your developers a heads up as to where things should go.
Lets start things out by outlining the [...]]]></description>
			<content:encoded><![CDATA[<p>This is an idea that I’ve been throwing around for a while now, and I have implemented in a couple of project.&#160; The basic idea is to extend the basic master page, by adding more ContentPlaceholders, to give your developers a heads up as to where things should go.</p>
<p>Lets start things out by outlining the various parts of a web page:</p>
<ul>
<li>Title</li>
<li>Header</li>
<li>Content</li>
<li>Footer</li>
<li>CSS includes</li>
<li>Script includes</li>
<li>JavaScript</li>
</ul>
<p>Typically, without eliciting some <a href="http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/">tricks</a>, there will be some JavaScript in your page, as there will be some part of the script that is dynamic.&#160; But best case, all of the JavaScript that you need can be put into a separate file.&#160; But even then, if we are talking 5 lines of JavaScript I will probably give you a pass if you keep it in the file.</p>
<p>But what I want to do is encourage <strike>best</strike> better practices.&#160; CSS is declared at the top, JavaScript at the bottom, html in the middle, code you want to run right after the page loads here.</p>
<p>So here is a typical MasterPage after I’ve made a few modifications:</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="background-color: #ffff00">&lt;%@ Master Language=&quot;C#&quot; Inherits=&quot;System.Web.Mvc.ViewMasterPage&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="lnum2">   2:</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="lnum3">   3:</span> <span style="color: #0000ff">&lt;!</span><span style="color: #800000">DOCTYPE</span> <span style="color: #ff0000">html</span> <span style="color: #ff0000">PUBLIC</span> <span style="color: #0000ff">&quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot;</span> <span style="color: #0000ff">&quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;</span><span style="color: #0000ff">&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>&#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="lnum5">   5:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">html</span> <span style="color: #ff0000">xmlns</span><span style="color: #0000ff">=&quot;http://www.w3.org/1999/xhtml&quot;</span> <span style="color: #0000ff">&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> <span style="color: #0000ff">&lt;</span><span style="color: #800000">head</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">=&quot;server&quot;</span><span style="color: #0000ff">&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="lnum7">   7:</span>     <span style="color: #0000ff">&lt;</span><span style="color: #800000">title</span><span style="color: #0000ff">&gt;&lt;</span><span style="color: #800000">asp:ContentPlaceHolder</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">=&quot;TitleContent&quot;</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">=&quot;server&quot;</span> <span style="color: #0000ff">/&gt;&lt;/</span><span style="color: #800000">title</span><span style="color: #0000ff">&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="lnum8">   8:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">head</span><span style="color: #0000ff">&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="lnum9">   9:</span> <span style="color: #0000ff">&lt;</span><span style="color: #800000">body</span><span style="color: #0000ff">&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="lnum10">  10:</span>         <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:ContentPlaceHolder</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">=&quot;MainContent&quot;</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">=&quot;server&quot;</span><span style="color: #0000ff">&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="lnum11">  11:</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="lnum12">  12:</span>         <span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:ContentPlaceHolder</span><span style="color: #0000ff">&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="lnum13">  13:</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="lnum14">  14:</span>     <span style="background-color: #ffff00">&lt;%</span>
<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> = Html.IncludeScript(<span style="color: #006080">&quot;~/Scripts/jquery-1.3.2.min.js&quot;</span>) </pre>
<p><!--CRLF--><span style="background-color: #ffff00">%&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="lnum15">  15:</span>     <span style="color: #0000ff">&lt;</span><span style="color: #800000">asp:ContentPlaceHolder</span> <span style="color: #ff0000">ID</span><span style="color: #0000ff">=&quot;ScriptIncludesContent&quot;</span> <span style="color: #ff0000">runat</span><span style="color: #0000ff">=&quot;server&quot;</span><span style="color: #0000ff">&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="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>     <span style="color: #0000ff">&lt;/</span><span style="color: #800000">asp:ContentPlaceHolder</span><span style="color: #0000ff">&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="lnum18">  18:</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="lnum19">  19:</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: #0000ff">&gt;</span>
<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>&#160; </pre>
<p><!--CRLF-->
<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>     $(document).ready(MasterLoadPage);</pre>
<p><!--CRLF-->
<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>     </pre>
<p><!--CRLF-->
<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>     <span style="color: #0000ff">function</span> MasterLoadPage(){</pre>
<p><!--CRLF-->
<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>         &lt;asp:ContentPlaceHolder ID=<span style="color: #006080">&quot;DocumentReadyContent&quot;</span> runat=<span style="color: #006080">&quot;server&quot;</span>&gt;</pre>
<p><!--CRLF-->
<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-->
<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>         &lt;/asp:ContentPlaceHolder&gt;</pre>
<p><!--CRLF-->
<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-->
<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-->
<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>     </pre>
<p><!--CRLF--><span style="color: #0000ff">&lt;/</span><span style="color: #800000">script</span><span style="color: #0000ff">&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="lnum20">  20:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">body</span><span style="color: #0000ff">&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="lnum21">  21:</span> <span style="color: #0000ff">&lt;/</span><span style="color: #800000">html</span><span style="color: #0000ff">&gt;</span></pre>
<p><!--CRLF--></div>
</div>
<p>You can see that I’ve added some extra placeholders in the code there.&#160; </p>
<p>But does any of this suck? Yes.&#160; When you add a page that implements this master page, you will get all of the appropriate content areas, but they will all assume that you are going to add html/text to them.&#160;&#160;&#160; The consequence is that the DocumentReadyContent Content area that is generated cannot help you with any JavaScript/Css intellesense.&#160; </p>
<p>To some extent, that is still ok, as I am looking to minimize the amount of JavaScript and css in my pages…you could say the pain is disserved. <img src='http://elegantcode.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> &#160;&#160; But what would be nice is if we could add a language indicator to the Content element. (hint: Microsoft VS team, I’m looking at you).&#160;&#160; </p>
<p>If you also think adding language indicators would be cool, vote here: <a href="http://aspnet.uservoice.com/forums/41199-general/suggestions/487773-make-language-specific-contentplaceholders-">http://aspnet.uservoice.com/forums/41199-general/suggestions/487773-make-language-specific-contentplaceholders-</a></p>
<p>Happy hacking.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/02/18/extend-your-master-pages/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My Media Center Setup</title>
		<link>http://elegantcode.com/2010/01/04/my-media-center-setup/</link>
		<comments>http://elegantcode.com/2010/01/04/my-media-center-setup/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 03:48:13 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Esoterica]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2010/01/04/my-media-center-setup/</guid>
		<description><![CDATA[So the time finally came, TIVO had to go.&#160; No worries, Tivo had a good run – 6 years.&#160; But the analog to digital conversion was not kind to Tivo.&#160; The digital converter box I got to be friends with Tivo, but it just never worked out between them.&#160; Plus, I was wanting more than [...]]]></description>
			<content:encoded><![CDATA[<p>So the time finally came, TIVO had to go.&#160; No worries, Tivo had a good run – 6 years.&#160; But the analog to digital conversion was not kind to Tivo.&#160; The digital converter box I got to be friends with Tivo, but it just never worked out between them.&#160; Plus, I was wanting more than Tivo could deliver.&#160; I wanted Hulu, Netflix, DVDs, games, etc.&#160; It was time for Tivo to go.</p>
<p>So being a Microsoft kind of guy, the move to Windows 7 Media Center was an easy one.&#160; The hard part was assembling the hardware was all I needed.&#160; Plus being overly Dutch (I’m first generation American, but still) I really wanted to do it on the cheap.&#160; That means cheaper than a comparable Tivo with a year of subscription costs.</p>
<p>I should also note here: I do not subscribe to cable, satellite TV, or even Netflix.&#160; I don’t like monthly fees.&#160; All I have is an antenna, which gives ms about 20 channels (four of which are PBS, which is fine by me).&#160; So even though I get a lot fewer channels, I still like to record programs, sometimes two programs at the same time (double header football games on Fox and CBS).</p>
<p>My Hardware:</p>
<p><strong>The PC</strong>: I got a <a href="http://www.dell.com/us/en/corp/desktops/inspiron-zino-hd/pd.aspx?refid=inspiron-zino-hd&amp;s=corp">Dell Zino HD (Inspiron 400)</a>.&#160; You can get this machine for as little as $250, but after upgrades I ended up spending $400 ($40 was shipping).&#160; I upgraded to a dual-core CPU, got the wireless package, and got the blue cover.&#160; One thing I should have done was upgrade the hard drive.&#160; The default is 250 GB, you can go up to 1 TB.&#160; I’m going to make up the difference with an external hard drive.&#160; I also have a few other computers with a bit over a TB of storage on the network.&#160; Also, I plan on using the HDMI connection to connect to my TV (flat screen) for both picture and sound.</p>
<p><strong>Signal Converter:</strong> <a href="http://www.amazon.com/SiliconDust-HDHomeRun-HDHR-US-Definition-Television/dp/B0010Y414Q">SiliconDust HDHomeRun 250</a> ($130).<strong>&#160;</strong>one thing the Zino does not do is take an antenna signal.&#160; This is a dual signal tuner which is exactly what I was looking for.&#160; So the HDHomeRun converts the signal and exports it to your network.&#160;&#160; The box also comes with software to install on your computer(s) that will connect your pc and Media Center to the HDHomeRun.&#160; Downside of this approach was that now I needed a small router next to my TV (I don’t have a Cat5 line to my TV).&#160; That wasn’t a big issue for me, I have a spare router.</p>
<p><strong>Remote:</strong> <a href="http://www.amazon.com/Windows-Control-Infrared-Receiver-Ultimate/dp/B00224ZDFY/ref=sr_1_1?ie=UTF8&amp;s=electronics&amp;qid=1262658991&amp;sr=8-1">Vista MCE Remote Control (VRC-1100).</a> ($22).&#160; Let me say, this was a mistake on my part.&#160; The remote works, but this one kind of stinks.&#160; There is a big round button in the middle that acts as a mouse – which is OK.&#160; But the controls on the top half are all badly positioned.&#160; I like a remote you don’t have to look at to use, this one fails that test.&#160; Buy a better remote than I did.</p>
<p><strong>Done.</strong>&#160; Actually, that is all you need.&#160; I spent about $550.&#160; A comparable TiVo would cost $408 plus about a $13 monthly fee, that would run $560 for the first year.&#160; So I don’t feel too bad about how I did.&#160; But do note, this is a basic system.</p>
<p><strong>How does Media Center compare to Tivo (software-y-softare&#160;&#160; **cough** mono-y-mono)</strong></p>
<p>I’m comparing Media Center to TiVo Version 2 here.&#160; I don’t have the latest version.</p>
<ul>
<li>I get 2 weeks of programming with Media Center – 3 days with Tivo (I don’t subscribe).</li>
<li>TiVo has a way to skip ahead 15 minutes.&#160; I miss that with Media Center.</li>
<li>Media Center still plays sound when fast forwarding.&#160; I love that feature.</li>
<li>Media Center can skip ahead 15 seconds.&#160; Also a great feature.</li>
<li>Lots of Plug-ins for Media Center.&#160; Lots.&#160; TiVo…not so much. (that I know of)</li>
<li>Media Center is still Win7, I know what I can do with that.&#160; TiVo is a bit more closed minded.</li>
<li>I can view the channel guide and still watch the current program with Media Center.&#160; Then view a single channel, and sort by time or name.&#160; Beautiful.</li>
<li>With home network, I can view all of my family pictures stored on other computers.&#160; Same with videos.</li>
</ul>
<p>Verdict: I’m happy with Media Center.</p>
<p><strong>What is next?</strong> Lets start with what I’m missing.&#160; </p>
<p>1.&#160; Surround sound is one.&#160; I need to figure that part out.&#160;&#160; But for now I’m keeping my old DVD player and receiver handy (I also have an old receiver that does not take HDMI).&#160; But this system is perfectly fine for all of my kids movies (they don’t like the subwoofer anyway).&#160; But I’d like to find some USB-type surround sound device.</p>
<p>2. BlueRay.&#160; I did not get a BlueRay player…actually, I don’t care about that.&#160; I see BlueRay on the huge displays at stores, I just don’t see enough of difference to care.</p>
<p>3. <a href="http://www.amazon.com/gp/product/B000B6MLTQ/ref=s9_simi_gw_s0_p63_i1?pf_rd_m=ATVPDKIKX0DER&amp;pf_rd_s=center-4&amp;pf_rd_r=1ZRZGQD8ZEDFAT3DMRCE&amp;pf_rd_t=101&amp;pf_rd_p=470939031&amp;pf_rd_i=507846">Xbox 360 Controller</a>.&#160; I also want this box to be a <a href="http://www.hanselman.com/blog/creatingmyownmamearcadecabinetmameformediacenterpcandthexarcadejoystick.aspx">gaming machine</a>.&#160; The more uses I can get of the machine the better.&#160; I’m not serious enough to get <a href="http://www.xgaming.com/">really crazy</a>, but a few games here and there would be nice. </p>
<p>4. WebCam?&#160; I have a thought of installing Skype and turning it into a phone as well.&#160; But maybe not.</p>
<p>So, in conclusions, I’ve happy with the Media Center system I was able to put together.&#160; It does what I want, it is extensible, and there are plug-ins to do almost anything else I want (local weather).</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2010/01/04/my-media-center-setup/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Authenticated web services calls with Asp.Net MVC</title>
		<link>http://elegantcode.com/2009/12/06/authenticated-web-services-calls-with-asp-net-mvc/</link>
		<comments>http://elegantcode.com/2009/12/06/authenticated-web-services-calls-with-asp-net-mvc/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 01:01:49 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[Asp.Net MVC]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[JQuery]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/12/06/authenticated-web-services-calls-with-asp-net-mvc/</guid>
		<description><![CDATA[I’ve been encountering a problem as of late.&#160; I’m creating a lot of “Single Page Pattern” web applications.&#160; This means you load the page once, then handle everything else via web service calls.
And if you have ever worked on web applications you should be familiar with the “user went to lunch” issue (session timeout).&#160; User [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been encountering a problem as of late.&#160; I’m creating a lot of “Single Page Pattern” web applications.&#160; This means you load the page once, then handle everything else via web service calls.</p>
<p>And if you have ever worked on web applications you should be familiar with the “user went to lunch” issue (session timeout).&#160; User leaves for an hour, comes back to your web page, and expects it to continue working.&#160; Unfortunately the session timed out, and now you have to refresh a bunch o’ crap.&#160;&#160; Another version of the problem, the “.ASPXFORMSAUTH” cookies gets deleted.&#160; Either way, your web site stop just working and the user blames you.</p>
<p>The fix is to have the user log in again.&#160; Normally this is simple, when the user does something, then the page is refreshed and redirected to the login page (as assigned in the web.config).&#160; That is the standard web model.&#160; Unfortunately it does not work in this case.</p>
<p>Web services complicate things.&#160; When inside a web method request, redirects do not work, and even worse if you are using JQuery “load” method (which loads html directly into an element), then you get the login page inside of a div.&#160; But more often, your web client code is expecting JSON, and will be getting html (an error page or the login page).</p>
<p>So my current solution it to wrap up the <a href="http://docs.jquery.com/Ajax">JQuery AJAX methods</a> with my own methods.&#160; This way I can check the users authentication (another web method).&#160; If I see the user is not logged in, I redirect to the login page.&#160; The other web method is killed via the page redirect.</p>
<p>Here is my wrapper:</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">var</span> ajax = {</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>     _lastAuthCheck: <span style="color: #0000ff">new</span> Date().getTime(),</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>     getJSON: <span style="color: #0000ff">function</span>(url, data, callback) {</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>         ajax.CheckAuthentication();</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">return</span> $.getJSON(url, data, callback);</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--></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>     post: <span style="color: #0000ff">function</span>(url, data, callback, type) {</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>         ajax.CheckAuthentication();</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>         <span style="color: #0000ff">return</span> $.post(url, data, callback, type);</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>     },</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>     load: <span style="color: #0000ff">function</span>(destination, url, <span style="color: #0000ff">params</span>, callback) {</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>         ajax.CheckAuthentication();</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>         destination.load(url, <span style="color: #0000ff">params</span>, callback);</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>     CheckAuthentication: <span style="color: #0000ff">function</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>         <span style="color: #0000ff">if</span> (!TimeToCheckAuth()) <span style="color: #0000ff">return</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>         $.getJSON('&lt;%=Url.Action(&quot;IsAuthenticated&quot;, &quot;Account&quot;)%&gt;', <span style="color: #0000ff">null</span>, <span style="color: #0000ff">function</span>(result) {</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">if</span> (!result) {</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>                 window.location = <span style="color: #006080">'&lt;%=Url.Action(&quot;LogOn&quot;, &quot;Account&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="lnum20">  20:</span>             } <span style="color: #0000ff">else</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="lnum21">  21:</span>                 ajax._lastAuthCheck = <span style="color: #0000ff">new</span> Date().getTime();</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>             }</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>         });</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">function</span> TimeToCheckAuth(){</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>             <span style="color: #0000ff">var</span> currentTime = <span style="color: #0000ff">new</span> Date().getTime();</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>             <span style="color: #0000ff">var</span> diff = currentTime - ajax._lastAuthCheck;</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>&#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="lnum29">  29:</span>             <span style="color: #0000ff">return</span> (diff &gt; 5000);</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>         }</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> };</pre>
<p><!--CRLF--></div>
</div>
<p>Now with the wrapper in place I switch my $.ajax, $.get, $.post calls to ajax.ajax, ajax.get, ajax.post.&#160; All the parameters should stay the&#160; same.</p>
<p>Notice one thing, I’m mixing in Url.Action calls in that code.&#160; I should add that this code is in a separate file for me, not in my web form page.&#160; If you want to get more of an idea of how I do that, check out my post on <a href="http://elegantcode.com/2009/11/07/asp-net-mvc-javascriptview/">Asp.Net MVC JavaScriptView</a>.</p>
<p>Now the web method, IsAuthenticated, is about as simple as you can get:</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> [AcceptGet]</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">public</span> JsonResult IsAuthenticated()</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> {</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>     <span style="color: #0000ff">return</span> Json(User.Identity.IsAuthenticated);</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> }</pre>
<p><!--CRLF--></div>
</div>
<p>But back to the JavaScript, there are a couple of other things going on here.&#160; First off, the authentication check will happen at the same time actual web method call.&#160; I banking on the theory that the authentication check will return before the other method.&#160;&#160; Second, I put an extra check in the method, so at most the authentication check will only happen once ever 5 seconds.&#160; Adjust as you feel necessary. </p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/12/06/authenticated-web-services-calls-with-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>JQuery Validator plus Element IDs, and Names</title>
		<link>http://elegantcode.com/2009/11/23/jquery-validator-plus-element-ids-and-names/</link>
		<comments>http://elegantcode.com/2009/11/23/jquery-validator-plus-element-ids-and-names/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 05:10:30 +0000</pubDate>
		<dc:creator>Chris Brandsma</dc:creator>
				<category><![CDATA[JQuery]]></category>

		<guid isPermaLink="false">http://elegantcode.com/2009/11/23/jquery-validator-plus-element-ids-and-names/</guid>
		<description><![CDATA[OK, just discovered an interesting implementation detail of JQuery Validator (one that I should have known about already as well).
OK, if you have a form where the inputs of the for have both id and name&#160; attributes, the name attributes trump id.
So if you have this:


   1: &#60;input type='type' id='RegisterUserName' name='userName' /&#62;


Then you [...]]]></description>
			<content:encoded><![CDATA[<p>OK, just discovered an interesting implementation detail of JQuery Validator (one that I should have known about already as well).</p>
<p>OK, if you have a form where the inputs of the for have both id and name&#160; attributes, the name attributes trump id.</p>
<p>So if you have this:</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">input</span> <span style="color: #ff0000">type</span><span style="color: #0000ff">='type'</span> <span style="color: #ff0000">id</span><span style="color: #0000ff">='RegisterUserName'</span> <span style="color: #ff0000">name</span><span style="color: #0000ff">='userName'</span> <span style="color: #0000ff">/&gt;</span></pre>
<p><!--CRLF--></div>
</div>
<p>Then you write the validation against ‘user&#8217;Name’, not ‘RegisterUserName’.</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: #006080">&quot;RegisterForm&quot;</span>).validate({</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>     rules: { userName: {required: <span style="color: #0000ff">true</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> });</pre>
<p><!--CRLF--></div>
</div>
<p>If you do not you will get all sorts of strange null exception errors (which in JavaScript means something returned as ‘undefined’.</p>
<h2>How this happens</h2>
<p>People have been talking about the great flexibility of Asp.Net MVC for a while now, but there are a few things to be aware of.&#160; One of them is multiple forms.&#160; </p>
<p>Say you have a web page that has two forms on it, one to register users, the other to log users in.&#160;&#160; Both forms have ‘username’ and ‘password’ fields.&#160;&#160; Asp.Net MVC still cannot get you around the need to keep ids unique – but names can be reused.&#160;&#160; These names are also read by Asp.Net Action Controllers.&#160; So if you have multiple forms all submitting to the same Controller Action, as long as the name attributes are set it will hook up.</p>
<p>Anyway, this is a short post, mostly for myself, so I don’t spend two hours figuring this out again.</p>
]]></content:encoded>
			<wfw:commentRss>http://elegantcode.com/2009/11/23/jquery-validator-plus-element-ids-and-names/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
