<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>chris carter's web log</title><link>http://panteravb.com/</link><description>chris carter's thoughts on programming and anything else I feel like</description><copyright>chris carter</copyright><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ChrisCartersWebLog" type="application/rss+xml" /><item><title>I Heart Balsamiq Mockups</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/412416074/i-heart-balsamiq-mockups.ashx</link><description>&lt;p&gt;This post is a little info on how I went about coming up with a design for a winform app I'm building.&lt;/p&gt;
&lt;p&gt;OK.&amp;nbsp; I still use paper.&amp;nbsp; This is what I started with today(very bad quality photo of paper):&lt;/p&gt;
&lt;p&gt;&lt;img src="/blog/image/showbywidth/74.ashx?width=800" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Although simple, it took me awhile to figure out where to start on the UI.&amp;nbsp; Once this was on paper, I had a better idea of where I wanted to start with &lt;a href="http://www.balsamiq.com/"&gt;Balsamiq Mockups&lt;/a&gt;.&amp;nbsp; After a pretty short amount of time(like maybe 30 minutes), I came up with this(&lt;strong&gt;click to enlarge&lt;/strong&gt;):&lt;/p&gt;
&lt;p&gt;&lt;a href="/blog/image/show/75.ashx" target="_blank"&gt;&lt;img border="0" src="/blog/image/showbywidth/75.ashx?width=800" alt="Balsamiq Mockups" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I spent very little time in the winform designer once i mocked up what I wanted.  I ended up with this as a first cut:&lt;/p&gt;
&lt;p&gt;&lt;img src="/blog/image/show/76.ashx" alt="" /&gt;&lt;/p&gt;</description><pubDate>Mon, 06 Oct 2008 00:16:16 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F10%2F5%2Fi-heart-balsamiq-mockups.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/10/5/i-heart-balsamiq-mockups.ashx</feedburner:origLink></item><item><title>Part 2: Test Driven Development In Practice</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/410692152/part-2-test-driven-development-in-practice.ashx</link><description>&lt;p&gt;OK. Here's part 2 of the TDD in practice dealio.  I decided a screencast would be appropriate.  I'm just getting over a cold so my voice is shot, this is a silent movie.&lt;/p&gt;
&lt;p&gt;In &lt;a href="http://panteravb.com/blog/posts/2008/10/3/part-1-test-driven-development-in-practice.ashx"&gt;part 1&lt;/a&gt; I typed in code that I want, to solve my problem. Most of the code did not exist.  So in part 2, we need to create everything that's missing and make the test pass.  Play the video to see how I did it(I used all &lt;a href="http://www.devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/"&gt;CodeRush&lt;/a&gt; features to generate code - with a little manual intervention; but most of this can also be done with raw Visual Studio shortcuts).&lt;/p&gt;
&lt;p&gt;&lt;object width="798" height="623" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0"&gt;
&lt;param name="movie" value="http://panteravb.com/codecasts/tdd-part2.swf" /&gt;
&lt;param name="quality" value="high" /&gt;
&lt;param name="bgcolor" value="#FFFFFF" /&gt; &lt;embed width="798" height="623" src="http://panteravb.com/codecasts/tdd-part2.swf" quality="high" bgcolor="#FFFFFF" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;</description><pubDate>Fri, 03 Oct 2008 22:40:39 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F10%2F3%2Fpart-2-test-driven-development-in-practice.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/10/3/part-2-test-driven-development-in-practice.ashx</feedburner:origLink></item><item><title>Part 1: Test Driven Development In Practice</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/410442602/part-1-test-driven-development-in-practice.ashx</link><description>&lt;p&gt;&lt;a href="http://panteravb.com/blog/posts/2008/10/3/part-2-test-driven-development-in-practice.ashx"&gt;Go here for part 2.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ok, so I've been meaning to do a screencast on this, i've done one but it's lame.&amp;nbsp; I figured I'd do more a photo slash journal-ish type thing and describe my real world(yes this is for an actual project) usage of TDD.&amp;nbsp; So here goes, I just typed the following into my test, this is what I want to do:&lt;/p&gt;
&lt;p&gt;&lt;img src="/blog/image/show/73.ashx" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;And that's pretty much it.&amp;nbsp; Notice the red squiggly lines? Yep, I haven't created that stuff yet, cuz this is what I want to do, not what I've done.&amp;nbsp; Next part will be making those red lines go away...&lt;/p&gt;</description><pubDate>Fri, 03 Oct 2008 16:23:43 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F10%2F3%2Fpart-1-test-driven-development-in-practice.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/10/3/part-1-test-driven-development-in-practice.ashx</feedburner:origLink></item><item><title>Muppet F*cker</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/410420584/muppet-fcker.ashx</link><description>&lt;p&gt;That's one of the funniest terms I've heard in awhile.&amp;nbsp; I heard it during the &lt;a href="http://www.infoq.com/presentations/archaeopteryx-bowkett"&gt;brilliant presentation&lt;/a&gt; by &lt;a href="http://gilesbowkett.blogspot.com/"&gt;Giles Bowkett&lt;/a&gt; recorded at &lt;a href="http://rubyfringe.com"&gt;RubyFringe&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Fri, 03 Oct 2008 16:09:16 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F10%2F3%2Fmuppet-fcker.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/10/3/muppet-fcker.ashx</feedburner:origLink></item><item><title>IModelBinder with AutoBinder</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/409742111/imodelbinder-with-autobinder.ashx</link><description>&lt;p&gt;Today I noticed &lt;a href="http://blog.maartenballiauw.be/post/2008/10/02/Using-the-ASPNET-MVC-ModelBinder-attribute-Second-part.aspx"&gt;this post&lt;/a&gt; on the ModelBinder attribute that ships with Preview 5 of ASP.NET MVC. I looked at the example and it doesn't make any sense.&amp;nbsp; I had come up with something I call AutoBinder and until today didn't think it was anything worth mentioning.&amp;nbsp; I could swear I saw somewhere that something like this would be included in the RTM of MVC but I can't remember where I saw that.&lt;/p&gt;
&lt;h3&gt;IModelBinder&lt;/h3&gt;
&lt;p&gt;IModelBinder is a simple interface with one method to implement, it looks like this:&lt;/p&gt;
&lt;pre&gt;
&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;interface&lt;/span&gt; IModelBinder {
  &lt;span class="type"&gt;object&lt;/span&gt; GetValue(ControllerContext controllerContext, &lt;span class="type"&gt;string&lt;/span&gt; modelName, Type modelType, ModelStateDictionary modelState);
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/pre&gt;
&lt;h3&gt;AutoBinder&lt;/h3&gt;
&lt;p&gt;AutoBinder simply implements that interface like this:&lt;/p&gt;
&lt;pre&gt;
&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;class&lt;/span&gt; AutoBinder&amp;lt;TModel&amp;gt; : IModelBinder &lt;span class="statement"&gt;where&lt;/span&gt; TModel : &lt;span class="storageClass"&gt;class&lt;/span&gt;, &lt;span class="statement"&gt;new&lt;/span&gt;(){
  &lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="type"&gt;object&lt;/span&gt; GetValue(ControllerContext controllerContext, &lt;span class="type"&gt;string&lt;/span&gt; modelName,
    Type modelType, ModelStateDictionary modelState){
    &lt;span class="repeat"&gt;return&lt;/span&gt; AutoBinder.UpdateFrom&amp;lt;TModel&amp;gt;(controllerContext);
  }
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
5
6
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/pre&gt;
&lt;p&gt;And AutoBinder.UpdateFrom looks like this:&lt;/p&gt;
&lt;pre&gt;
&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;static&lt;/span&gt; T UpdateFrom&amp;lt;T&amp;gt;(ControllerContext controllerContext) &lt;span class="statement"&gt;where&lt;/span&gt; T : &lt;span class="storageClass"&gt;class&lt;/span&gt;, &lt;span class="statement"&gt;new&lt;/span&gt;(){
  T result = &lt;span class="statement"&gt;new&lt;/span&gt; T();
  NameValueCollection form = controllerContext.HttpContext.Request.Form;
  &lt;span class="repeat"&gt;foreach&lt;/span&gt; (PropertyDescriptor property &lt;span class="statement"&gt;in&lt;/span&gt; TypeDescriptor.GetProperties(result)){
	&lt;span class="type"&gt;object&lt;/span&gt; &lt;span class="statement"&gt;value&lt;/span&gt; = &lt;span class="constant"&gt;null&lt;/span&gt;;
	&lt;span class="comment"&gt;//if the property type is boolean, make sure it's not an array, the&lt;/span&gt;
	&lt;span class="comment"&gt;//default behavior of Html.CheckBox is to create the checkbox, plus&lt;/span&gt;
	&lt;span class="comment"&gt;//a hidden field with the same name as the checkbox, to cover the behavior&lt;/span&gt;
	&lt;span class="comment"&gt;//of when a checkbox is unchecked, it won't get posted&lt;/span&gt;
	&lt;span class="conditional"&gt;if&lt;/span&gt; (property.PropertyType == &lt;span class="statement"&gt;typeof&lt;/span&gt;(&lt;span class="type"&gt;bool&lt;/span&gt;)){
	  &lt;span class="type"&gt;string&lt;/span&gt;[] values = form[property.Name].Split(&lt;span class="character"&gt;','&lt;/span&gt;);
	  &lt;span class="conditional"&gt;if&lt;/span&gt; (values.Length &amp;gt; &lt;span class="number"&gt;0&lt;/span&gt;){
		&lt;span class="statement"&gt;value&lt;/span&gt; = ConvertUtils.ChangeType(values[&lt;span class="number"&gt;0&lt;/span&gt;], property.PropertyType);
	  }
	}&lt;span class="conditional"&gt;else&lt;/span&gt;{
	  &lt;span class="statement"&gt;value&lt;/span&gt; = ConvertUtils.ChangeType(form[property.Name], property.PropertyType);
	}
	property.SetValue(result, &lt;span class="statement"&gt;value&lt;/span&gt;);
  }
  &lt;span class="repeat"&gt;return&lt;/span&gt; result;
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
5
6
7
8
9
&lt;span class='nthLineNumber'&gt;10&lt;/span&gt;
11
12
13
14
15
16
17
18
19
&lt;span class='nthLineNumber'&gt;20&lt;/span&gt;
21
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/pre&gt;
&lt;h3&gt;Using AutoBinder&lt;/h3&gt;
&lt;p&gt;Using this requires either registering the types with their appropriate binder at app startup or adorning your models with the ModelBuilder attribute like so:&lt;/p&gt;
&lt;pre&gt;
&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;[ModelBinder(&lt;span class="statement"&gt;typeof&lt;/span&gt;(AutoBinder&amp;lt;Customer&amp;gt;))]
&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;class&lt;/span&gt; Customer{
&lt;span class="comment"&gt;//guts of Customer here&lt;/span&gt;
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/pre&gt;
&lt;p&gt;Now in a controller we might have a method that looks like this:&lt;/p&gt;
&lt;pre&gt;
&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;[AcceptVerbs(&lt;span class="string"&gt;"POST"&lt;/span&gt;)]
&lt;span class="storageClass"&gt;public&lt;/span&gt; ActionResult Edit(Customer customer){
&lt;span class="comment"&gt;//blah blah blah&lt;/span&gt;
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/pre&gt;
&lt;p&gt;Assuming that all of the fields on the form have the same name attribute as the properties on the model, the customer arg will be mapped up with the posted form values automagically through the ModelBinder attribute.&lt;/p&gt;
&lt;p&gt;Anyway, here's the spectacular example: &lt;a href="http://panteravb.com/downloads/modelbinder.zip"&gt;ModelBinder.zip&lt;/a&gt;.&amp;nbsp; It assumes that you have Preview 5 of ASP.NET MVC installed.&lt;/p&gt;</description><pubDate>Thu, 02 Oct 2008 22:16:51 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F10%2F2%2Fimodelbinder-with-autobinder.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/10/2/imodelbinder-with-autobinder.ashx</feedburner:origLink></item><item><title>Holy Shitballs Batman! jQuery and Microsoft? Seriously??</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/405759374/holy-shitballs-batman-jquery-and-microsoft-seriously.ashx</link><description>&lt;p&gt;Wow.&amp;nbsp; This was only posted 6 hours ago and i feel like I'm the last to hear &lt;a href="http://weblogs.asp.net/scottgu/archive/2008/09/28/jquery-and-microsoft.aspx"&gt;the news&lt;/a&gt;. &lt;/p&gt;</description><pubDate>Sun, 28 Sep 2008 22:18:48 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F9%2F28%2Fholy-shitballs-batman-jquery-and-microsoft-seriously.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/9/28/holy-shitballs-batman-jquery-and-microsoft-seriously.ashx</feedburner:origLink></item><item><title>Partyin with Balsamiq Mockups</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/405631366/partyin-with-balsamiq-mockups.ashx</link><description>&lt;p&gt;I'm havin alot of fun with &lt;a href="http://www.balsamiq.com/"&gt;Balsamiq Mockups&lt;/a&gt; today.&amp;nbsp; Here's my latest endeavor, I'm still learning so it's not great but it did help get over a hump with the project i'm working on.&lt;/p&gt;
&lt;p&gt;&lt;a target="_blank" title="click to enlarge" href="/blog/image/show/72.ashx"&gt;&lt;img border="0" src="/blog/image/showbywidth/72.ashx?width=800" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;</description><pubDate>Sun, 28 Sep 2008 17:58:09 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F9%2F28%2Fpartyin-with-balsamiq-mockups.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/9/28/partyin-with-balsamiq-mockups.ashx</feedburner:origLink></item><item><title>Quick, Somebody Give Me A Credit Card Number</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/399833833/quick-somebody-give-me-a-credit-card-number.ashx</link><description>&lt;p&gt;&lt;img alt="" src="/blog/image/show/71.ashx" /&gt;&lt;/p&gt;</description><pubDate>Mon, 22 Sep 2008 12:54:10 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F9%2F22%2Fquick-somebody-give-me-a-credit-card-number.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/9/22/quick-somebody-give-me-a-credit-card-number.ashx</feedburner:origLink></item><item><title>Sketchy Food Tracker</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/394167677/sketchy-food-tracker.ashx</link><description>&lt;p&gt;via &lt;a href="http://www.tobinharris.com/2008/9/15/get-that-sketchy-look-in-your-wireframes"&gt;Tobin&lt;/a&gt;, i decided to check out &lt;a href="http://www.balsamiq.com/"&gt;Balsamiq Mockups&lt;/a&gt;.&amp;nbsp; Wow.&amp;nbsp; This tool is frickin awesome.&lt;/p&gt;
&lt;h3&gt;Food Tracker&lt;/h3&gt;
&lt;p&gt;As part of &lt;a href="http://www.emerfit.com/blog/2008/09/15/monday-080915/"&gt;starting a cross fit&lt;/a&gt; program, I'm tracking(trying to anyway), I want to get better at tracking what I eat.&amp;nbsp; Since I suck at coming up sample project ideas, i figured that a food tracking app would be a good way to play around with ASP.NET MVC and MonoRail as a sample application.&amp;nbsp; I had come up with a sketch of the input form this weekend, but this morning the one I did with Balsamiq's online tool came out WAY better.&amp;nbsp; Check out the sketch:&lt;/p&gt;
&lt;p&gt;&lt;img style="float: left;" src="/blog/image/show/70.ashx" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;The tools is surprisingly fun to use.&amp;nbsp; There are a ton of controls to pick from and anything you choose you can customize the text and data.&lt;/p&gt;
&lt;p&gt;The grid in my sketch was a snap to set up, drag a grid, type in what you want for the header text, and a few rows beneath and you're done.&lt;/p&gt;
&lt;p&gt;The designer also hasguidelines, so when you drag a control, similar to Visual Studio's WinForm designer, you get the vertical and horizontal guidelines that help you make stuff look good.&lt;/p&gt;
&lt;p&gt;Anyway, if you have drawn diagrams of screen layouts before on paper, it's worth takin a look at.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Tue, 16 Sep 2008 11:23:36 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F9%2F16%2Fsketchy-food-tracker.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/9/16/sketchy-food-tracker.ashx</feedburner:origLink></item><item><title>More Html.ValidateTextBox</title><link>http://feeds.feedburner.com/~r/ChrisCartersWebLog/~3/393411278/more-htmlvalidatetextbox.ashx</link><description>&lt;p&gt;OK.&amp;nbsp; So I added some server side rule checking as a backup to the client side stuff.&amp;nbsp; In order to test this out, I had to turn off client side validation.&amp;nbsp; Right now it only returns a list of validation error messages, but I have some plans for that mechanism.&amp;nbsp; The controller method that handles the form post now looks like this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;[AcceptVerbs(&lt;span class="string"&gt;"POST"&lt;/span&gt;)]
&lt;span class="storageClass"&gt;public&lt;/span&gt; ActionResult Edit(&lt;span class="type"&gt;int&lt;/span&gt; id, Customer customer)
{
  customer.ID = id;
  &lt;span class="conditional"&gt;if&lt;/span&gt; (!Model.IsValid(customer))
  {
    ViewData[&lt;span class="string"&gt;"errormessages"&lt;/span&gt;] = Model.GetErrorMessages(customer);
    &lt;span class="repeat"&gt;return&lt;/span&gt; View(customer);
  }

  RepoFactory.Get&amp;lt;Customer&amp;gt;().Save(customer);
  &lt;span class="repeat"&gt;return&lt;/span&gt; &lt;span class="statement"&gt;this&lt;/span&gt;.RedirectToAction(&lt;span class="string"&gt;"index"&lt;/span&gt;);
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
5
6
7
8
9
&lt;span class='nthLineNumber'&gt;10&lt;/span&gt;
11
12
13
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;The only change i made to the Customer class so far was that I added a custom model binder attribute to the customer.&amp;nbsp; That attribute looks like this:&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;class&lt;/span&gt; CustomerBinder : IModelBinder
{
  &lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="type"&gt;object&lt;/span&gt; GetValue(ControllerContext controllerContext,
    &lt;span class="type"&gt;string&lt;/span&gt; modelName,
    Type modelType,
    ModelStateDictionary modelState)
  {
    NameValueCollection form = controllerContext.HttpContext.Request.Form;
    &lt;span class="repeat"&gt;return&lt;/span&gt; &lt;span class="statement"&gt;new&lt;/span&gt; Customer
    {
      FirstName = form[&lt;span class="string"&gt;"FirstName"&lt;/span&gt;],
      LastName = form[&lt;span class="string"&gt;"LastName"&lt;/span&gt;]
    };
  }
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
5
6
7
8
9
&lt;span class='nthLineNumber'&gt;10&lt;/span&gt;
11
12
13
14
15
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;And the customer class looks like this(i updated the validation attribute constructors to match the changes i made.&lt;/p&gt;
&lt;p&gt;&lt;table cellpadding='0' cellspacing='0' class='irisContainer' style='border-collapse: collapse; border-spacing:0'&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='margin: 0; padding:0'&gt;&lt;/td&gt;
&lt;td rowspan='2' class='highlighted output'&gt;&lt;pre class="cs highlighted"&gt;&lt;span class="normal"&gt;[ModelBinder(&lt;span class="statement"&gt;typeof&lt;/span&gt;(CustomerBinder))]
&lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="storageClass"&gt;class&lt;/span&gt; Customer : IModel
{
  &lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="type"&gt;int&lt;/span&gt; ID { get; set; }

  [ValidateLength(&lt;span class="number"&gt;3&lt;/span&gt;, &lt;span class="number"&gt;30&lt;/span&gt;,
    &lt;span class="string"&gt;"First name must be between 3 and 30 characters in length."&lt;/span&gt;, &lt;span class="constant"&gt;true&lt;/span&gt;)]
  &lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="type"&gt;string&lt;/span&gt; FirstName { get; set; }

  [ValidateMaxLength(&lt;span class="number"&gt;30&lt;/span&gt;,
    &lt;span class="string"&gt;"Last name is required and cannot exceed 30 characters."&lt;/span&gt;, &lt;span class="constant"&gt;true&lt;/span&gt;)]
  &lt;span class="storageClass"&gt;public&lt;/span&gt; &lt;span class="type"&gt;string&lt;/span&gt; LastName { get; set; }
}
&lt;/span&gt;&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class='output lineNumbers'&gt;
&lt;pre class='lineNumbers'&gt;&lt;span class='lineNumbers'&gt;1
2
3
4
5
6
7
8
9
&lt;span class='nthLineNumber'&gt;10&lt;/span&gt;
11
12
13
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;
&lt;p&gt;and the server side validation ends up rendering the following view(reminiscent of lammo validation summary in webforms):&lt;/p&gt;
&lt;p&gt;&lt;img src="/blog/image/show/69.ashx" alt="" /&gt;&lt;/p&gt;</description><pubDate>Mon, 15 Sep 2008 16:32:43 GMT</pubDate><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetItemData?uri=ChrisCartersWebLog&amp;itemurl=http%3A%2F%2Fpanteravb.com%2Fblog%2Fposts%2F2008%2F9%2F15%2Fmore-htmlvalidatetextbox.ashx</feedburner:awareness><feedburner:origLink>http://panteravb.com/blog/posts/2008/9/15/more-htmlvalidatetextbox.ashx</feedburner:origLink></item><feedburner:awareness>http://api.feedburner.com/awareness/1.0/GetFeedData?uri=ChrisCartersWebLog</feedburner:awareness></channel></rss>
