<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;A04EQ3w5fip7ImA9WhRRGU8.&quot;"><id>tag:blogger.com,1999:blog-19251193</id><updated>2011-12-03T10:31:42.226-06:00</updated><category term="wcf" /><category term="WebForms" /><category term="SQL" /><category term="twitterizer" /><category term="SpecFlow" /><category term="XML" /><category term="Sitefinity" /><category term="conference" /><category term="WebFormContrib" /><category term="nunit" /><category term="recap" /><category term="ASP.NET" /><category term="misc" /><category term="ADO.NET" /><category term="mvc" /><category term="visual studio" /><category term="jquery" /><category term="TDD" /><category term="css" /><category term="moq" /><category term="opinion" /><category term="flickr" /><category term="BDD" /><category term="generics" /><category term="HTML" /><category term="Castle Validators" /><category term="log4net" /><category term="Google API" /><category term="NHibernate" /><category term="design" /><category term="StructureMap" /><category term="Fluent NHibernate" /><category term="LINQ to SQL" /><category term="fluent" /><category term="JavaScript" /><category term="AutoMapper" /><category term="blogging" /><category term="SSIS" /><category term="FluentHtml" /><category term=".NET" /><category term="WatiN" /><title>Deran Schilling, Learner</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://derans.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://derans.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default?start-index=11&amp;max-results=10&amp;redirect=false&amp;v=2" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>85</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>10</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/derans" /><feedburner:info uri="derans" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>derans</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><entry gd:etag="W/&quot;DEUASXc_cSp7ImA9WhRTGEQ.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-5439504720993254388</id><published>2011-11-09T21:19:00.001-06:00</published><updated>2011-11-09T21:37:28.949-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-09T21:37:28.949-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term=".NET" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><title>Refactoring MVC Routes</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float: right; margin: 0 20px; padding: 0px 0px 0px 0px;"&gt;
&lt;script type="text/javascript"&gt;
tweetmeme_source = 'derans';
tweetmeme_service = 'is.gd';
&lt;/script&gt;
&lt;script src="http://tweetmeme.com/i/scripts/button.js" type="text/javascript"&gt;
&lt;/script&gt;

&lt;/div&gt;
Some of my team members and myself are participating in the Houston AIR competition this weekend and we are building our project this week. Of course we’ll have to rebuild it from scratch on Saturday, but hopefully it’ll just be a bunch of re-typing and no surprises. Anyhow, one of my duties on the team is to configure MVC and the interfaces we’ll need and all that jazz. So when I went to setup the routes, I was surprised again at how flexible it all is to setup. Typically you can get by with the default route, but not in our case this time. Basically we wanted to have these routes:
&lt;br/&gt;&lt;br/&gt;
/story/give&lt;br/&gt;
/story/{id} &lt;br/&gt;
/feature/{id} &lt;br/&gt;
/prayer/{id}     &lt;br/&gt;
/{pagename}&lt;br/&gt;
&lt;br/&gt;
By the way, our assigned charity is a church in Houston called the Household of Faith Church - South Acres. At first I had this: (which is TOTALLY RIDCULOUS, but I wanted to see them all)
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: white;"&gt;routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Home"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;""&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Home" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"give/story"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Feature"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"feature/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Feature"&lt;/span&gt;&lt;span style="color: white;"&gt;, id=&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer"&lt;/span&gt;&lt;span style="color: white;"&gt;, id = &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story"&lt;/span&gt;&lt;span style="color: white;"&gt;, id = &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"About"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"About"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"About"&lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Directions"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Directions"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Directions" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"SiteMap"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"SiteMap"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"SiteMap" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Help"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Help"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Help" &lt;/span&gt;&lt;span style="color: white;"&gt;});
&lt;/span&gt;&lt;/pre&gt;
I typically setup my routes early on because I usually know what I want the URLs to be and it helps when naming my actions on the controllers. So obvioulsy we only have one controller because it’s not a large site and they all kinda go together, but what’s up with all the actions on the route configuration? Ridiculous right? So let’s get rid of all that mess like this:
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: white;"&gt;routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"give/story"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Feature"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"feature/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Feature"&lt;/span&gt;&lt;span style="color: white;"&gt;, id=&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Prayer"&lt;/span&gt;&lt;span style="color: white;"&gt;, id = &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story/{id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story"&lt;/span&gt;&lt;span style="color: white;"&gt;, id = &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional });

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Page"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"{viewname}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GetStatic"&lt;/span&gt;&lt;span style="color: white;"&gt;, viewname = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Home" &lt;/span&gt;&lt;span style="color: white;"&gt;});
&lt;/span&gt;&lt;/pre&gt;
Simple enough right? So I created an action called GetStatic that just accepts the view name for that page. The action looks like this:
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;ViewResult &lt;/span&gt;&lt;span style="color: white;"&gt;GetStatic(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;string &lt;/span&gt;&lt;span style="color: white;"&gt;viewname)
{
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;View(viewname);
}
&lt;/span&gt;&lt;/pre&gt;
Now let’s address the other redundant mess I have here…the {feature/prayer/story}/{id} route. Basically we’re going to do that and add a constraint to the route like this:
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: white;"&gt;routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"give/story"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GiveStory" &lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"WebSectionRoute"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"{WebType}/{Id}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ Controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GetWebSection"&lt;/span&gt;&lt;span style="color: white;"&gt;, Id = &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;UrlParameter&lt;/span&gt;&lt;span style="color: white;"&gt;.Optional }, &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{WebType = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Story|Feature|Prayer"&lt;/span&gt;&lt;span style="color: white;"&gt;});

routes.MapRoute(
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Page"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"{viewname}"&lt;/span&gt;&lt;span style="color: white;"&gt;,
&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: white;"&gt;{ controller = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Main"&lt;/span&gt;&lt;span style="color: white;"&gt;, action = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"GetStatic"&lt;/span&gt;&lt;span style="color: white;"&gt;, viewname = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Home" &lt;/span&gt;&lt;span style="color: white;"&gt;});
&lt;/span&gt;&lt;/pre&gt;
So what this says is if the WebType contains story/feature/prayer then use this route otherwise keep on going. I can’t express enough the importance of the route order here. It’s an easy thing to miss and I’ve caught the missed order a few times for other developers and myself. Make sur eyou put them in the order they need to be in and not in some random order.
Well that’s it. Route configuration refactored and now it doesn’t have any redundant routes.
&lt;br/&gt;&lt;br/&gt;
&lt;b&gt;Thanks for reading!&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-5439504720993254388?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=v4NjMq8l3qU:vQl8hMqPOdo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=v4NjMq8l3qU:vQl8hMqPOdo:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=v4NjMq8l3qU:vQl8hMqPOdo:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/v4NjMq8l3qU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/5439504720993254388/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=5439504720993254388" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/5439504720993254388?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/5439504720993254388?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/v4NjMq8l3qU/refactoring-mvc-routes.html" title="Refactoring MVC Routes" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/11/refactoring-mvc-routes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQASH06eCp7ImA9WhdbF0g.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-4979810061473123740</id><published>2011-10-16T02:57:00.001-05:00</published><updated>2011-10-16T03:05:49.310-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-16T03:05:49.310-05:00</app:edited><title>How to easily turn your L2S objects into interfaces</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float: right; margin: 20px; padding: 0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;
tweetmeme_source = 'derans';
tweetmeme_service = 'is.gd';
&lt;/script&gt;&lt;br /&gt;
&lt;script src="http://tweetmeme.com/i/scripts/button.js" type="text/javascript"&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;I know it’s been a while since I posted an actual post, but I think this one will be fun. So let’s get to it…&lt;br /&gt;
In one of our recent code reviews, we found several methods that looked almost identical. All of these methods were just for lookup tables that populated a dropdown. So…this is what we did:&lt;br /&gt;
We had a repository with something like GetDepartmentList and GetStatusList that looked something like this:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;SampleRepository &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ISampleRepository
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupDepartment&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetDepartmentList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.LookupDepartments
                                 .Where(x =&amp;gt; !x.IsDeleted)
                                 .OrderBy(x=&amp;gt;x.Name)
                                 .ToList();
        }

        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupStatus&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetStatusList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.LookupStatus
                                 .Where(x =&amp;gt; !x.IsDeleted)
                                 .OrderBy(x=&amp;gt;x.Status)
                                 .ToList();
        }
    }&lt;/span&gt;&lt;/pre&gt;&lt;i&gt;Note: we do not return L2S objects typically, but to make this example simple, I’m going to pretend that we do.&lt;/i&gt;&lt;br /&gt;
The first thing we did was changed the type returned by both methods to return ILookupObject instead of the L2S objects…like this:&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;SampleRepository &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ISampleRepository
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetDepartmentList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.LookupDepartments
                                 .Where(x =&amp;gt; !x.IsDeleted)
                                 .OrderBy(x=&amp;gt;x.Name)
                                 .Cast&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;()
                                 .ToList();
        }

        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetStatusList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.LookupStatus
                                 .Where(x =&amp;gt; !x.IsDeleted)
                                 .OrderBy(x=&amp;gt;x.Status)
                                 .Cast&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;()
                                 .ToList();
        }
    }&lt;/span&gt;&lt;/pre&gt;Obviously this cast isn’t going to work so we need to finagle our dbml. It’s easy to extend the L2S objects without modifying the dbml. I actually prefer never to touch the dbml itself unless absolutely necessary because I like to Ctrl+A, del, drag everything back over whenever I want :)&lt;br /&gt;
So to extend the classes, we just need to do this:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public partial class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupDepartment &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public string &lt;/span&gt;&lt;span style="color: white;"&gt;DisplayName { &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;get &lt;/span&gt;&lt;span style="color: white;"&gt;{ &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;Name; } }
    }

    &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public partial class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupStatus &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public string &lt;/span&gt;&lt;span style="color: white;"&gt;DisplayName { &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;get &lt;/span&gt;&lt;span style="color: white;"&gt;{ &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;Status;} }
    }&lt;/span&gt;&lt;/pre&gt;Done.&lt;br /&gt;
Now we need to revisit our SampleRepository and extract out all the redundant code so we have something like this:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetList&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;Expression&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;Func&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;T, &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;object&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;&amp;gt; orderby) &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;where &lt;/span&gt;&lt;span style="color: white;"&gt;T : &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;class&lt;/span&gt;&lt;span style="color: white;"&gt;, &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject
        &lt;/span&gt;&lt;span style="color: white;"&gt;{
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.GetTable&amp;lt;T&amp;gt;()
                                 .Where(x =&amp;gt; !x.IsDeleted)
                                 .OrderBy(orderby)
                                 .Cast&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;()
                                 .ToList();
        }&lt;/span&gt;&lt;/pre&gt;All we’ve done is made a generic GetList method that takes in the orderby. You could easily make this not dependent on the datacontext too, but to keep this post simple, we won’t do that now. As you can see, this looks almost exactly like our original method with the exception of dc.GetTable&amp;lt;T&amp;gt;(), which is built-in to the datacontext class. All we need to do is pass it the type so it knows from which table to pull data. It’s actually a pet peeve of mine for a lookup type dropdown to not be ordered, so I’m forcing the orderby method and not giving another option.&lt;br /&gt;
The repository looks like this now:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;RefactoredSampleRepository &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ISampleRepository
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;private static &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetList&amp;lt;T&amp;gt;(&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;Expression&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;Func&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;T, &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;object&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;&amp;gt; orderby) &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;where &lt;/span&gt;&lt;span style="color: white;"&gt;T : &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;class&lt;/span&gt;&lt;span style="color: white;"&gt;, &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject
        &lt;/span&gt;&lt;span style="color: white;"&gt;{
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;using &lt;/span&gt;&lt;span style="color: white;"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;var &lt;/span&gt;&lt;span style="color: white;"&gt;dc = &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupSampleDataContext&lt;/span&gt;&lt;span style="color: white;"&gt;())
                &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;dc.GetTable&amp;lt;T&amp;gt;()
                         .Where(x =&amp;gt; !x.IsDeleted)
                         .OrderBy(orderby)
                         .Cast&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;()
                         .ToList();
        }

        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetDepartmentList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;GetList&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupDepartment&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;(x=&amp;gt;x.Name);
        }

        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; GetStatusList()
        {
            &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;return &lt;/span&gt;&lt;span style="color: white;"&gt;GetList&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupStatus&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt;(x=&amp;gt;x.Status);
        }
    }&lt;/span&gt;&lt;/pre&gt;Nice and pretty…I don’t like the orderby expression here, but I think it’s the best option for now. There is another way, but it jacks up L2S for inserts and updates. So, if you KNOW your not going to ever update or insert a new record for a lookup, then you could do this:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public partial class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;LookupStatus &lt;/span&gt;&lt;span style="color: white;"&gt;: &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        [&lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;Column&lt;/span&gt;&lt;span style="color: white;"&gt;(Name=&lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"Status"&lt;/span&gt;&lt;span style="color: white;"&gt;)]
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public string &lt;/span&gt;&lt;span style="color: white;"&gt;DisplayName { &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;get&lt;span style="color: white;"&gt;;&lt;/span&gt; set&lt;span style="color: white;"&gt;;&lt;/span&gt; &lt;/span&gt;&lt;span style="color: white;"&gt;}
    }
&lt;/span&gt;&lt;/pre&gt;What this does is maps the DisplayName to the Status column so you could just do .OrderBy(x=&amp;gt;x.DisplayName) instead of passing in the orderby. The reason you have to map the column is because you’ll get a “SQL has no supported translation…” error. You could also just rename the property Status to DisplayName in the dbml file itself.&lt;br /&gt;
&lt;i&gt;Also, it’s not recommended that you use multiple datacontexts according to l2sprof, but to make this simple, I did.&lt;/i&gt;&lt;br /&gt;
So now we can easily bind this to a dropdown via another helper method like this:&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: #cc7832;"&gt;public static class &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;extensions
    &lt;/span&gt;&lt;span style="color: white;"&gt;{
        &lt;/span&gt;&lt;span style="color: #cc7832;"&gt;public static void &lt;/span&gt;&lt;span style="color: white;"&gt;BindDropDownTo(&lt;/span&gt;&lt;span style="color: #cc7832;"&gt;this &lt;/span&gt;&lt;span style="color: #ffc66d;"&gt;DropDownList &lt;/span&gt;&lt;span style="color: white;"&gt;ddl, &lt;/span&gt;&lt;span style="color: #2b91af;"&gt;IList&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;ILookupObject&lt;/span&gt;&lt;span style="color: white;"&gt;&amp;gt; data)
        {
            ddl.DataSource = data;
            ddl.DataTextField = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"DisplayName"&lt;/span&gt;&lt;span style="color: white;"&gt;;
            ddl.DataValueField = &lt;/span&gt;&lt;span style="color: #a5c25c;"&gt;"ID"&lt;/span&gt;&lt;span style="color: white;"&gt;;
            ddl.DataBind();
        }
    }&lt;/span&gt;&lt;/pre&gt;So in the UI, we just do this: (if using webforms)&lt;br /&gt;
&lt;pre class="code" style="background: #000;"&gt;&lt;span style="color: white;"&gt;ddlStatus.BindDropDownTo(rep.GetStatusList());&lt;/span&gt;&lt;/pre&gt;If you’re using MVC, you could create an htmlhelper to do something similar.&lt;br /&gt;
Alright, I think that’s it. Please post if you have better methods or have any questions.&lt;br /&gt;
&lt;b&gt;Thanks for reading!&lt;/b&gt;&lt;br /&gt;
&lt;a rev="vote-for" href="http://dotnetshoutout.com/Deran-Schilling-Learner-How-to-easily-turn-your-L2S-objects-into-interfaces"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fderans.blogspot.com%2F2011%2F10%2Fhow-to-easily-turn-your-l2s-objects.html" style="border:0px"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-4979810061473123740?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=M_xGQFmlhWA:cydN1ipK3rU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=M_xGQFmlhWA:cydN1ipK3rU:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=M_xGQFmlhWA:cydN1ipK3rU:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/M_xGQFmlhWA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/4979810061473123740/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=4979810061473123740" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/4979810061473123740?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/4979810061473123740?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/M_xGQFmlhWA/how-to-easily-turn-your-l2s-objects.html" title="How to easily turn your L2S objects into interfaces" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/10/how-to-easily-turn-your-l2s-objects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYARHY-fCp7ImA9WhdbEkw.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-7567776189139234281</id><published>2011-10-09T20:29:00.000-05:00</published><updated>2011-10-09T20:29:05.854-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-09T20:29:05.854-05:00</app:edited><title>Can't believe it...</title><content type="html">A whole month went by without me realizing that I didn't blog. It's insane to me how fast a month goes by these days. I'm going to have to step up my blogging again. &lt;br /&gt;
&lt;br /&gt;
At least vacation time is coming up soon, so I'll have more free time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-7567776189139234281?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=MQPBnNxDoq4:r3KvzB8Nmac:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=MQPBnNxDoq4:r3KvzB8Nmac:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=MQPBnNxDoq4:r3KvzB8Nmac:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/MQPBnNxDoq4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/7567776189139234281/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=7567776189139234281" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/7567776189139234281?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/7567776189139234281?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/MQPBnNxDoq4/cant-believe-it.html" title="Can't believe it..." /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/10/cant-believe-it.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D08DQXs_fip7ImA9WhdXE08.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-6210282605505309118</id><published>2011-08-25T21:28:00.003-05:00</published><updated>2011-08-25T21:31:10.546-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-25T21:31:10.546-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="css" /><title>Blogging just to Blog…I mean Styling Tips!</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:10px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;Lately I have not felt like blogging, but I’m committed to at least once a month. I think the primary reason I haven’t felt th need to blog is because I haven’t really spent much time developing lately. I’ve been spending a lot of my time on user experience and interface design.&lt;/p&gt;  &lt;p&gt;I thought I’d share a few styling tricks that are too easy not to do because they add a lot to usability.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Changing the style of a row on hover. This allows the end user to easily see which row they’re looking at instead of having to trace the line.     &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;table tr:hover td {background: #e7e7e7}       &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Changing the style of an input on focus. This allows the end-user to easily see where they’re at in a form without much thought.     &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;input:focus {border: solid 1px #f90}       &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;    &lt;li&gt;Changing the style of a hyperlink on hover. Granted this one has been around forever, but it’s a great one.     &lt;br /&gt;      &lt;br /&gt;&lt;em&gt;a:hover {background: #333; color: #fff}&lt;/em&gt;&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;There are most definitely hundreds more, but these are a few of my favorites to use on a project. Also note that they do &lt;strong&gt;&lt;em&gt;NOT &lt;/em&gt;&lt;/strong&gt;work in all browsers.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-6210282605505309118?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=xdHxZzra6fI:lSHsrMSKd5Q:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=xdHxZzra6fI:lSHsrMSKd5Q:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=xdHxZzra6fI:lSHsrMSKd5Q:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/xdHxZzra6fI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/6210282605505309118/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=6210282605505309118" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/6210282605505309118?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/6210282605505309118?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/xdHxZzra6fI/blogging-just-to-blogi-mean-styling.html" title="Blogging just to Blog…I mean Styling Tips!" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/08/blogging-just-to-blogi-mean-styling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQFQns6cCp7ImA9WhdSEEk.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-3272228488938406633</id><published>2011-07-18T23:03:00.002-05:00</published><updated>2011-07-18T23:05:13.518-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-18T23:05:13.518-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="conference" /><title>Big Design Conference 2011 Recap</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:20px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;Once again I find myself writing a conference recap without notes. Let me go ahead and apologize to all the speakers just in case I leave out something or misunderstood their presentation. &lt;/p&gt;  &lt;p&gt;So…this year’s conference wasn’t as good as last year’s to me. I think there are a few reasons…&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;1. No free donuts (even though I didn’t care for the orange topping last year…I still liked them…I mean, they’re donuts)&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;2. No free sodas and snacks between sessions. These are important for any successful conference in my opinion :)&lt;/p&gt; &lt;/blockquote&gt;  &lt;blockquote&gt;   &lt;p&gt;3. It wasn’t all new to me…I knew more of what to expect and what people were going to talk about…not the case last year.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;As for the presentations, I’m unsure if they were the same or not as good because I lost perspective as a non-conf-rook. Everything last year was new and fresh and this year, not so much. This year’s conference theme was more about all your customer experiences meshing into one big great customer experience via whatever outlet…last year there seemed to be more of a theme on how to leverage the social web. Anyhow, if you’d like to read that recap you can &lt;a href="http://derans.blogspot.com/2010/05/big-design-conference-2010-recap.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Day 1:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Keynote by &lt;a href="http://civilrightsmuseum.org/" target="_blank"&gt;Gwen Harmon&lt;/a&gt; (&lt;a href="http://twitter.com/ncrmuseum" target="_blank"&gt;@ncrmuseum&lt;/a&gt;)       &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Emotional design makes the whole experience almost life haltering, even if temporarily. &lt;/li&gt;        &lt;li&gt;The &lt;a href="http://civilrightsmuseum.org/" target="_blank"&gt;National Civil Rights Museum&lt;/a&gt; looks like an amazing place to go visit. &lt;/li&gt;        &lt;li&gt;Engineers are honest to the point of their own death. I had never heard this joke, it was funny.          &lt;ul&gt;           &lt;li&gt;&lt;em&gt;The Joke&lt;/em&gt;: an engineer, a lawyer, and a something else(should’ve taken notes) are all on death row via guillotine. The something else is up, they release the blade and it stops…so he’s let off…the lawyer gets up there the blade drops and it stops again…so he’s let off…the engineer has his turn and looks up and says oh I see your problem. &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;The &lt;a href="http://civilrightsmuseum.org/" target="_blank"&gt;National Civil Rights Museum&lt;/a&gt; is looking to do a lot of upgrades, which will make it even more appealing to visit and learn. &lt;a href="http://www.civilrightsmuseum.org/?page_id=85" target="_blank"&gt;You can donate now if you’d like to help.&lt;/a&gt;          &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Mobile Design at the Speed of Thought by &lt;a href="http://www.bottlerocketapps.com/" target="_blank"&gt;Michael Griffith&lt;/a&gt; &lt;a href="http://www.twitter.com/CrypticDevice" target="_blank"&gt;@crypticdevice&lt;/a&gt;       &lt;br /&gt;&lt;strong&gt;&lt;a href="http://prezi.com/9i5so2vlsm9b/design-for-mobile-at-the-speed-of-thought/" target="_blank"&gt;Prezi Show&lt;/a&gt;&lt;/strong&gt;       &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Two ways to communicate – talking &amp;amp; drawing (i.e. not reading requirements) &lt;/li&gt;        &lt;li&gt;Ideas are disposable…we’ll make more! &lt;/li&gt;        &lt;li&gt;Downloaded the 106 &amp;amp; Park iPhone app. Played with the voting “game”…highest thus far…30 votes &lt;/li&gt;        &lt;li&gt;Don’t turn a website into an app! An app is a companion to a website. &lt;/li&gt;        &lt;li&gt;Buy this book…&lt;a href="http://www.amazon.com/gp/product/006097625X" target="_blank"&gt;Understanding Comics The Invisible Art by Scott McCloud&lt;/a&gt;           &lt;br /&gt;&lt;em&gt;Also…I bought this book…and 5 others…stupid conference making me spend $            &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Designing a Cohesive Customer Experience by &lt;a href="http://www.bubblemountain.com/" target="_blank"&gt;Elizabeth Rosenzweig&lt;/a&gt; (&lt;a href="http://twitter.com/#!/ElizRosenzweig" target="_blank"&gt;@elizrosenzweig&lt;/a&gt;) and &lt;a href="http://www.usabilitysciences.com/" target="_blank"&gt;Scott Gunter&lt;/a&gt;       &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Get to sessions on time because standing for an hour kinda sucks &lt;/li&gt;        &lt;li&gt;With that said, I know they were talking a lot about Ikea…but I missed most of that part…&lt;/li&gt;        &lt;li&gt;Don’t shop at Pottery Barn because they will stalk you…at least one of the audience members made it sound this way…I believe it &lt;/li&gt;        &lt;li&gt;Apparently we are capable of cloaking something for 3 nano seconds according to Elizabeth via MSNBC. &lt;a href="http://www.msnbc.msn.com/id/43743463/ns/technology_and_science-innovation/t/cloaking-device-edits-out-events-space-time/" target="_blank"&gt;Read more here if you wish&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;The jist of this one was to make all of your customer experiences aware of each other…if I create a shopping list on kroger.com and it knows which store I shop at…give me my list on my phone by aisle and sort it based on location so I don’t do 18 laps around the store…seriously they should do this…          &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Free Your Mind: Using UX Checklists to Focus on What's Important by &lt;a href="http://survey-sage.org/" target="_blank"&gt;Elisa Miller&lt;/a&gt; (&lt;a href="http://twitter.com/elisakm" target="_blank"&gt;@elisakm&lt;/a&gt;)       &lt;br /&gt;&lt;a href="http://www.slideshare.net/elisakm/the-power-of-ux-checklists" target="_blank"&gt;Download Slide Deck&lt;/a&gt;      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Make good checklists &lt;/li&gt;        &lt;li&gt;Buy this book - &lt;a href="http://gawande.com/the-checklist-manifesto" target="_blank"&gt;The Checklist Manifesto by Atul Gawande&lt;/a&gt;. (Recommended in more than one presentation I attended) &lt;/li&gt;        &lt;li&gt;I actually started making quite a few checklists today…the most important: Post-Deployment Review Checklist for applications team         &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Forget your MBA: Managing in a Creative Culture by &lt;a href="http://behindcompanies.com/" target="_blank"&gt;Marcelo Somers&lt;/a&gt; (&lt;a href="http://www.twitter.com/marcelosomers" target="_blank"&gt;@marcelosomers&lt;/a&gt;)       &lt;br /&gt;&lt;a href="http://www.slideshare.net/msomers/forget-your-mba-managing-a-living-company" target="_blank"&gt;Download Slide Deck&lt;/a&gt;       &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;He’s a finance geek and a machead &lt;/li&gt;        &lt;li&gt;Companies are alive and they don’t live very long &lt;/li&gt;        &lt;li&gt;Focus on a few things and do them better than anyone else…Chipotle was his example &lt;/li&gt;        &lt;li&gt;The market changes…either change with it or die         &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Designing for Disabilities by &lt;a href="http://www.knowbility.org/" target="_blank"&gt;Sharron Rush&lt;/a&gt; (&lt;a href="http://twitter.com/#!/sharrush" target="_blank"&gt;@sharrush&lt;/a&gt;)       &lt;br /&gt;&lt;strong&gt;What I would’ve taken away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;I’ll admit it…I went for a nap over another session…HOWEVER, I would’ve gone to this one. I did stop by their booth because I plan to participate in their &lt;a href="http://www.knowbility.org/v/air-detail/AIR-Houston/35/" target="_blank"&gt;airhouston&lt;/a&gt; event in October and was looking for more info. I went to her session last year and it was very eye opening. Seriously, I literally just read the description and am very sorry I missed this one. &lt;em&gt;(Sure wish the description had been on some form of program rather than a print out with titles…hint hint!)            &lt;br /&gt;&lt;/em&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Closing Keynote by &lt;a href="http://www.userglue.com/" target="_blank"&gt;Russ Unger&lt;/a&gt; (who needs no introduction apparently, but gets one anyhow cause he’s special) (&lt;a href="http://twitter.com/russu" target="_blank"&gt;@russu&lt;/a&gt;)       &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;       &lt;ul&gt;       &lt;li&gt;Russ is very happy. &lt;em&gt;(last year he was angry so whatever he’s doing is working apparently)&lt;/em&gt;&lt;/li&gt;        &lt;li&gt;Russ is writing another book with Todd Zaki Warfel. Guerrilla UX Research Methods released November 15, 2011 according to Amazon.com &lt;/li&gt;        &lt;li&gt;Russ is still funny. &lt;/li&gt;        &lt;li&gt;Russ grew a “Texas” mustache just for us &lt;/li&gt;        &lt;li&gt;Russ thinks we should adopt Ice UX Framework…          &lt;ul&gt;           &lt;li&gt;stop collaborate and listen &lt;/li&gt;            &lt;li&gt;anything less than the best is a felony &lt;/li&gt;            &lt;li&gt;quick to the point to the point no faking &lt;/li&gt;            &lt;li&gt;and there may have been others &lt;/li&gt;         &lt;/ul&gt;       &lt;/li&gt;        &lt;li&gt;Russ likes &lt;a href="http://www.youtube.com/watch?v=TbiedguhyvM" target="_blank"&gt;a cat named Maru that gets into small boxes…the cat is funny&lt;/a&gt; &lt;/li&gt;        &lt;li&gt;Russ doesn’t know what he does for a living…or maybe people that he is close to don’t know…I don’t remember if he ever actually said &lt;/li&gt;        &lt;li&gt;Russ is excited to see what we do…I’m curious and a little excited too :) &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Day 2:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Opening Keynote by &lt;a href="http://globalmoxie.com/" target="_blank"&gt;Josh Clark&lt;/a&gt; (&lt;a href="http://twitter.com/globalmoxie" target="_blank"&gt;@globalmoxie&lt;/a&gt;)&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;I slept in due to lack of description. I need to know what I’m waking up for :)       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Accelerated Style Sheets: Less Typing, More Style by &lt;a href="http://wynn.fm/" target="_blank"&gt;Wynn Netherland&lt;/a&gt; (&lt;a href="http://www.twitter.com/pengwynn" target="_blank"&gt;@pengwynn&lt;/a&gt;) and Nathan Smith (&lt;a href="http://www.twitter.com/nathansmith" target="_blank"&gt;@nathansmith&lt;/a&gt;)&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Intended to go to this, but was caught up with packing and checking out of my room       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Designing for Change and Innovation by &lt;a href="http://www.uxarray.com/" target="_blank"&gt;Sara Summers&lt;/a&gt; (&lt;a href="http://www.twitter/com/sarasummers" target="_blank"&gt;@sarasummers&lt;/a&gt;)      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;&lt;a href="http://www.amazon.com/dp/0789742799?tag=dynamiprotot-20&amp;amp;camp=14573&amp;amp;creative=327641&amp;amp;linkCode=as1&amp;amp;creativeASIN=0789742799&amp;amp;adid=0V3X4TX64N416CXTN175&amp;amp;" target="_blank"&gt;She wrote a book.&lt;/a&gt; I was going to buy it, but then I saw it was using Expression Blend…&lt;/li&gt;      &lt;li&gt;Use your conference waiting time to ask people about ideas you have&lt;/li&gt;      &lt;li&gt;Make a feedback area in the blank walls of the surrounding cubes&lt;/li&gt;      &lt;li&gt;Walk the dog to think or actually just make time to think – I actually did that this morning on my way into work. I have a 45 minute commute and left the radio off so I could think…it was nice to talk to me.       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Innovation: Ideas are Just the Beginning by Adam Polansky (&lt;a href="http://www.twitter.com/@AdamtheIA" target="_blank"&gt;@adamtheia&lt;/a&gt;)      &lt;br /&gt;&lt;a href="http://www.slideshare.net/AdamtheIA/ideas-innovation-simple-premise-small-starts-7621074" target="_blank"&gt;&lt;strong&gt;Download Slide Deck&lt;/strong&gt;&lt;/a&gt;      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;An extra 30 minutes to look around…he was a bit quick&lt;/li&gt;      &lt;li&gt;Innovation = New Combinations (i.e. guy driving thinks “I like listening to radio”…”HEY NOW! I should add a radio in my car!”)&lt;/li&gt;      &lt;li&gt;Create a list of small bug fixes that can be fixed on your own time…present them…they’ll probably get added to the project list       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Slay the Legacy Code Beast by &lt;a href="http://developingux.com/" target="_blank"&gt;Caleb Jenkins&lt;/a&gt; (&lt;a href="http://www.twitter.com/CalebJenkins" target="_blank"&gt;@calebjenkins&lt;/a&gt;)      &lt;br /&gt;&lt;a href="http://www.slideshare.net/calebjenkins/taming-the-monster-legacy-code-beast" target="_blank"&gt;&lt;strong&gt;Download Slide Deck&lt;/strong&gt;&lt;/a&gt;      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Caleb is here to help.&lt;/li&gt;      &lt;li&gt;Caleb looks and talks a LOT like Dane Cook (I think Caleb might be funnier)&lt;/li&gt;      &lt;li&gt;Caleb references presentations from a year ago (I should’ve gone I guess)&lt;/li&gt;      &lt;li&gt;Caleb likes to ROOOOAAARRR (or just make monster noises…not sure how to spell what he was doing) and he enjoys audience participation&lt;/li&gt;      &lt;li&gt;Caleb once worked on a solution with over 68 projects…I think I woulda quit&lt;/li&gt;      &lt;li&gt;Here’s the jist:&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Know Your Foe (Legacy Code)&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;Don’t go changing stuff willy nilly&lt;/li&gt;          &lt;li&gt;Use dependency graphs&lt;/li&gt;       &lt;/ul&gt;        &lt;li&gt;Create a Safety Net &lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;Use Source Control&lt;/li&gt;          &lt;li&gt;Create Tests&lt;/li&gt;       &lt;/ul&gt;        &lt;li&gt;Divide and Conquer (pick your battles) &lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;The slideshare.net doesn’t do his presentation justice…I mean there was a really nifty split of the screen for this 3rd strategy announcement during his live presentation…it was truly amazing.&lt;/li&gt;       &lt;/ul&gt;     &lt;/ul&gt;      &lt;li&gt;Caleb will give you credit if he takes one of your pics from flickr…good to know&lt;/li&gt;      &lt;li&gt;I really enjoyed Caleb’s talk even though I don’t have every day battles with legacy monsters       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Designing for Awareness by &lt;a href="http://scrappyux.com/" target="_blank"&gt;Brian Sullivan&lt;/a&gt; (&lt;a href="http://twitter.com/brianksullivan" target="_blank"&gt;@BrianKSullivan&lt;/a&gt;) and &lt;a href="http://taylorcowanonline.com/" target="_blank"&gt;Taylor Cowan&lt;/a&gt; (&lt;a href="http://twitter.com/#!/tcowan" target="_blank"&gt;@tcowan&lt;/a&gt;)      &lt;br /&gt;&lt;strong&gt;&lt;a href="http://www.slideshare.net/BigDesignEvents/design-for-awareness-8618932" target="_blank"&gt;Download Slide Deck&lt;/a&gt;        &lt;br /&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Attention = Focus&lt;/li&gt;      &lt;li&gt;Distraction = Disorder&lt;/li&gt;      &lt;li&gt;Information’s price is attention…don’t be poor on attention&lt;/li&gt;      &lt;li&gt;Two types of attention…active and passive&lt;/li&gt;      &lt;li&gt;Do you multi-task? No you don’t.&lt;/li&gt;      &lt;li&gt;Checklists mentioned again&lt;/li&gt;      &lt;li&gt;Interruption vs Notification – Very important in design&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Interruption = Active Awareness (i.e. alert(‘Hey there!’);)&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;Only in emergency or dire situation&lt;/li&gt;       &lt;/ul&gt;        &lt;li&gt;Notifications = Passive Awareness (i.e. $(‘#thissmallredsquarenotification’).show();)&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;We process 400 billion bits of data per second passively&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;A lot less actively…2,000         &lt;br /&gt;&lt;/li&gt;     &lt;/ul&gt;   &lt;/ul&gt;    &lt;li&gt;Progressive Prototyping with HTML5, CSS3, and &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; by &lt;a href="http://zakiwarfel.com/" target="_blank"&gt;Todd Zaki Warfel&lt;/a&gt; (&lt;a href="http://twitter.com/zakiwarfel" target="_blank"&gt;@zakiwarfel&lt;/a&gt;)      &lt;br /&gt;&lt;a href="http://www.slideshare.net/zakiwarfel/prototyping-whtml5-and-css3" target="_blank"&gt;&lt;strong&gt;Download Slide Deck&lt;/strong&gt;&lt;/a&gt;      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Todd likes to cook&lt;/li&gt;      &lt;li&gt;Todd makes grayscale look sexy&lt;/li&gt;      &lt;li&gt;Todd does &lt;em&gt;not&lt;/em&gt; wireframe…I still do…I prototype too…mostly I wireframe to help me visualize the markup and gen the graphics&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Todd does this via sketches…I’m not that good&lt;/li&gt;        &lt;li&gt;I wonder what kind of markers he uses because they look like some awesome colors on his slideshow&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;Todd prefers to fail in a low cost environment…imagine that…&lt;/li&gt;      &lt;li&gt;Todd lays out the data first…then he styles&lt;/li&gt;      &lt;li&gt;Todd bragged a lot about not having a single image on his grayscale and it still looking “sexy”&lt;/li&gt;      &lt;li&gt;Todd then went on about the awesomeness of HTML5&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Specifically the progress and meter tags, which are pretty freakin sweet&lt;/li&gt;     &lt;/ul&gt;      &lt;li&gt;Todd gave a heads up about updating your reset.css…I’m glad he did because I have not&lt;/li&gt;      &lt;li&gt;Todd provides great coverage of CSS3 Selectors…I’ll let you look at his deck…same with his jQuery coverage&lt;/li&gt;      &lt;li&gt;Todd wrote a book and is working on the one mentioned earlier with Russ Unger…I bought the Prototyping book and am reading it now       &lt;br /&gt;&lt;/li&gt;   &lt;/ul&gt;    &lt;li&gt;Mobile &amp;amp; UX by &lt;a href="http://www.uie.com/" target="_blank"&gt;Jared Spool&lt;/a&gt;      &lt;br /&gt;Download Slide Deck…OH wait I haven’t received it via email yet…hopefully I emailed them correctly and will get it soon and hopefully I can get permission to share…if not…you shoulda been there :)      &lt;br /&gt;&lt;strong&gt;What I took away…&lt;/strong&gt;&lt;/li&gt;    &lt;ul&gt;     &lt;li&gt;Jared is flippin smart.&lt;/li&gt;      &lt;li&gt;Jared is great at teaching and entertaining…not once did I think, “hey! I’m learning a lot” (I did though)&lt;/li&gt;      &lt;ul&gt;       &lt;li&gt;Sturgeon’s Law – 90% of everything is crap. Are you in the 10%?&lt;/li&gt;        &lt;li&gt;Technology » Features » Experience&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;Jared realizes on an example here that his audience is a young one&lt;/li&gt;       &lt;/ul&gt;        &lt;li&gt;The Kano Model&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;User Satisfaction by Company Investment&lt;/li&gt;          &lt;li&gt;Must meet basic expectations (BEs) before excitement generators work&lt;/li&gt;          &lt;ul&gt;           &lt;li&gt;When BEs don’t work, you’re just pissing people off&lt;/li&gt;            &lt;li&gt;With time, delighters become BEs&lt;/li&gt;         &lt;/ul&gt;       &lt;/ul&gt;        &lt;li&gt;There were 3 questions to see how well formed your team is…but I don’t remember them. Hopefully I get that slide deck soon :)         &lt;br /&gt;What I remember…&lt;/li&gt;        &lt;ul&gt;         &lt;li&gt;the vision of the team and their experience with your design&lt;/li&gt;          &lt;li&gt;how long you spend watching your’s or your competitor’s design &lt;/li&gt;          &lt;li&gt;have you rewarded failure&lt;/li&gt;       &lt;/ul&gt;     &lt;/ul&gt;      &lt;li&gt;We are in an immature era, we are learning and the next few years are going to be very exciting and a bit scary if you like your privacy. Seriously…scary.&lt;/li&gt;   &lt;/ul&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Books Bought Due to Conference:&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/006097625X" target="_blank"&gt;Understanding Comics: The Invisible Art by Scott Mccloud&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/0321657292" target="_blank"&gt;Rocket Surgery Made Easy: The Do-It-Yourself Guide to Finding and Fixing Usability Problems by Steve Krug&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/0470185481" target="_blank"&gt;Handbook of Usability Testing: Howto Plan, Design, and Conduct Effective Tests by Jeffrey Rubin&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/0321767535" target="_blank"&gt;100 Things Every Designer Needs to Know About People by Susan Weinschenk&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/144030842X" target="_blank"&gt;Above the Fold: Understanding the Principles of Successful Web Site Design by Brian Miller&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.amazon.com/Prototyping-Practitioners-Todd-Zaki-Warfel/dp/1933820217/ref=sr_1_1?ie=UTF8&amp;amp;qid=1311041557&amp;amp;sr=8-1" target="_blank"&gt;Prototyping: A Practitioner’s Guide by Todd Zaki Warfel&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Other Stuff&lt;/strong&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;BigD still gives out awesome notebooks&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.geekinthesheets.com/" target="_blank"&gt;geeksinthesheets.com&lt;/a&gt; – seemed to be a popular booth…I wonder why?&lt;/li&gt;    &lt;li&gt;&lt;a href="http://campl.us/user/TScott" target="_blank"&gt;Cool Sketch Notes by T. Scott Stromberg&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;Rackspace…fanatical about advertising…seriously every slide deck I went to there was a Rackspace ad. We get the idea you’re crazy. (side note…I do use them and they’re pretty freaking awesome…also my brother works there so I can’t say anything bad…not that I’d want to)&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.slideshare.net/event/big-design-conference-2011/slideshows" target="_blank"&gt;Just found all the slideshows are being kept on slideshare.net…but not really.&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Check out #&lt;a href="https://twitter.com/#!/search/%23bigd11" target="_blank"&gt;bigd11&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;I love … makes grammar so easy :)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Suggestions for next year&lt;/strong&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;strong&gt;&lt;em&gt;&lt;font size="3"&gt;Printed programs with full descriptions of presentations and speakers&lt;/font&gt;&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt;    &lt;li&gt;Donuts &lt;/li&gt;    &lt;li&gt;Snacks &lt;/li&gt;    &lt;li&gt;Sodas &lt;/li&gt;    &lt;li&gt;Casino night that I know about at least a day or two before the night actually occurs…I would’ve loved to shoot some craps &lt;/li&gt;    &lt;li&gt;Donuts &lt;/li&gt;    &lt;li&gt;Maybe some bacon?? &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;That about does it. I enjoyed the conference and I’m excited about the user experiences I’ll be creating in the next year. Look forward to next year’s event!&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-3272228488938406633?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=9GQn-EI0Vw8:aI1Uj9WZzmM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=9GQn-EI0Vw8:aI1Uj9WZzmM:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=9GQn-EI0Vw8:aI1Uj9WZzmM:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/9GQn-EI0Vw8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/3272228488938406633/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=3272228488938406633" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/3272228488938406633?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/3272228488938406633?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/9GQn-EI0Vw8/big-design-conference-2011-recap.html" title="Big Design Conference 2011 Recap" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>1</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/07/big-design-conference-2011-recap.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAAQn09eyp7ImA9WhZbEk0.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-8201682172006077246</id><published>2011-06-16T00:03:00.002-05:00</published><updated>2011-06-16T00:05:43.363-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-16T00:05:43.363-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><title>jQuery Plugin: FunkyFocus v1.1</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:0 20px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;p&gt;I used by little plugin in a production environment today and found one bug and a couple needed features.&lt;/p&gt;  &lt;p&gt;The bug was with this code: &lt;/p&gt; &lt;pre&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;options.selectorOverride.replace('{id}', &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.id);&lt;/pre&gt;&lt;/pre&gt;&lt;pre&gt;&amp;#160;&lt;/pre&gt;&lt;pre&gt;Apparently it only replaces the first {id} found in the string. So I updated that line to this:&lt;/pre&gt;&lt;pre&gt;&amp;#160;&lt;/pre&gt;&lt;pre&gt;&lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; selector = options.selectorOverride.replace(/{id}/gi, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.id);&lt;/pre&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;One of the features I needed was a way to ignore certain elements. So I created a new option called notSelector and the default is ‘.ignore’. So basically all the selectors are $(selector).not(options.notSelector).whatever.&lt;/p&gt;&lt;p&gt;I also added a check for when you set the focus of an input via the code-behind in ASP.NET. &lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/derans/downloads/list"&gt;You can download the new version here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://derans.blogspot.com/p/jquery-funky-focus-demo.html"&gt;Check out the demo here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-8201682172006077246?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=gxFqxwvNGj8:v-uiMyOPT-k:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=gxFqxwvNGj8:v-uiMyOPT-k:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=gxFqxwvNGj8:v-uiMyOPT-k:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/gxFqxwvNGj8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/8201682172006077246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=8201682172006077246" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/8201682172006077246?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/8201682172006077246?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/gxFqxwvNGj8/jquery-plugin-funkyfocus-v11.html" title="jQuery Plugin: FunkyFocus v1.1" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/06/jquery-plugin-funkyfocus-v11.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UBR3szfyp7ImA9WhZVFEo.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-1922250264967962253</id><published>2011-05-26T23:33:00.003-05:00</published><updated>2011-05-26T23:40:56.587-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-26T23:40:56.587-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="design" /><title>New jQuery Plugin: FunkyFocus</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:0px 20px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;/div&gt;&lt;p&gt;So this jQuery plugin was built to help my end-users know immediately what section of a form they’re working on. Also, don’t blame me for the name. It was given to my new plugin by my wife because I couldn’t think of anything “catchy”. Basically what this thing does is changes the background of sections of forms or individual inputs. It’ll be better to post screenshots to get the idea…so…here you go…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-TsQWZTJJvUA/Td8pn73xPAI/AAAAAAAAASc/p664uF9Lca0/s1600-h/image3.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-AZV3TzkZeP4/Td8poQwRAgI/AAAAAAAAASg/Xy72sgrFCkI/image_thumb1.png?imgmax=800" width="486" height="496" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So as soon as you tab to the password textbox, you get this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-M98Ojs13T7M/Td8pohNpIlI/AAAAAAAAASk/VyezDrnt7rU/s1600-h/image8.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-Mk9k6hj8Hag/Td8ppFhBNFI/AAAAAAAAASo/t21qzguN_iY/image_thumb4.png?imgmax=800" width="478" height="492" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s how you use it:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Add a reference to &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Add a reference to the &lt;a href="http://code.google.com/p/derans/downloads/detail?name=jquery.funkyfocus.min.js"&gt;jquery.funkyfocus.js&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Add this line afterward: &lt;font color="#4bacc6"&gt;$('form').funkyFocus();&lt;/font&gt; &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;If you want to customize how you use it, you have some options. Here they are:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;class – default is selected &lt;/li&gt;    &lt;li&gt;sectionOnly – default is true &lt;/li&gt;    &lt;li&gt;selectorOverride – default is form#{id} input,form#{id} select,form#{id} textarea &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you don’t want to use &lt;em&gt;selected&lt;/em&gt; as your class, you’d use this code:&lt;/p&gt;  &lt;p&gt;&lt;font color="#4bacc6"&gt;&amp;#160;&amp;#160;&amp;#160; $('form').funkyFocus({class: 'yourclassname'}); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;If you don’t want to change the background, but want to change the individual input, do this:&lt;/p&gt;  &lt;p&gt;&lt;font color="#4bacc6"&gt;&amp;#160;&amp;#160;&amp;#160; $('form').funkyFocus({sectionOnly: false}); &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;It would look something like this (assuming you changed the selected style to have a green background):&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-TuBErikj820/Td8ppYNnfCI/AAAAAAAAASs/OCqckIqW3-I/s1600-h/image11.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-EtIGwCHZPDE/Td8ppqZSHAI/AAAAAAAAASw/js_qXimvFKU/image_thumb5.png?imgmax=800" width="177" height="152" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Here’s the actual plugin code:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;($) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    $.fn.funkyFocus = &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(options) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; defaults = {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;class&lt;/span&gt;: 'selected',&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    sectionOnly: &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    selectorOverride: 'form#{id} input,form#{id} select,form#{id} textarea'&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  };&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; options = $.extend(defaults, options);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;  &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.each(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; selector = options.selectorOverride.replace('{id}', &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.id);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    $(selector).&lt;span style="color: #0000ff"&gt;focus&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (options.sectionOnly)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).closest(&amp;quot;&lt;span style="color: #8b0000"&gt;div&lt;/span&gt;&amp;quot;).addClass(options.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).addClass(options.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    });&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    $(selector).&lt;span style="color: #0000ff"&gt;blur&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt;() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (options.sectionOnly)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).closest(&amp;quot;&lt;span style="color: #8b0000"&gt;div&lt;/span&gt;&amp;quot;).removeClass(options.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;      &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        $(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;).removeClass(options.&lt;span style="color: #0000ff"&gt;class&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    });&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        });&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    };&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;})(jQuery);&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;If you’d like to know &lt;a href="http://derans.blogspot.com/2010/04/jquery-plugin-to-trick-bots-from.html"&gt;how to create a jQuery plugin, check out this post&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/derans/downloads/list"&gt;Download the plugin here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://derans.blogspot.com/p/jquery-funky-focus-demo.html"&gt;Check out the demo here.&lt;/a&gt;&lt;/p&gt;&lt;p&gt;As always, please let me know if there’s a way to improve it. &lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;a rev="vote-for" href="http://dotnetshoutout.com/New-jQuery-Plugin-FunkyFocus"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fderans.blogspot.com%2F2011%2F05%2Fnew-jquery-plugin-funkyfocus.html" style="border:0px"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-1922250264967962253?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=g2lRhjYj9eg:r6NEd73zxTE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=g2lRhjYj9eg:r6NEd73zxTE:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=g2lRhjYj9eg:r6NEd73zxTE:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/g2lRhjYj9eg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/1922250264967962253/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=1922250264967962253" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/1922250264967962253?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/1922250264967962253?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/g2lRhjYj9eg/new-jquery-plugin-funkyfocus.html" title="New jQuery Plugin: FunkyFocus" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/-AZV3TzkZeP4/Td8poQwRAgI/AAAAAAAAASg/Xy72sgrFCkI/s72-c/image_thumb1.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/05/new-jquery-plugin-funkyfocus.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0EHSHg9eyp7ImA9WhZVGEw.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-8823321394358027303</id><published>2011-05-22T22:49:00.002-05:00</published><updated>2011-05-30T22:13:59.663-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-30T22:13:59.663-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><title>Contact Form Revisited with ASP.NET MVC 3, jQuery Validator, &amp; the jQuery Form Plugin</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:0px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;
tweetmeme_source = 'derans';
tweetmeme_service = 'is.gd';
&lt;/script&gt;&lt;br /&gt;
&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;p&gt;I recently added a partial contact view to my MVC3 project and thought I’d share since I did basically this &lt;a href="http://derans.blogspot.com/2010/03/contact-form-with-aspnet-mvc-castle.html"&gt;same post&lt;/a&gt; over a year ago with the original MVC. I stopped using the &lt;a href="http://www.castleproject.org/activerecord/documentation/v1rc1/usersguide/validation.html"&gt;Castle Validation&lt;/a&gt; because I’ve found that the MVC3 stuff is working for me now. I also am not using &lt;a href="http://mvccontrib.codeplex.com/wikipage?title=FluentHtml&amp;amp;referringTitle=Documentation"&gt;fluentHtml&lt;/a&gt; anymore because MVC3 uses that style now.&lt;/p&gt;&lt;p&gt;Okay…let’s get started.&lt;/p&gt;&lt;p&gt;We’ll start with the view model class like the &lt;a href="http://derans.blogspot.com/2010/03/contact-form-with-aspnet-mvc-castle.html"&gt;last post&lt;/a&gt;. By the way, if you’re not familiar with the way I setup my MVC projects, &lt;a href="http://derans.blogspot.com/2009/12/aspnet-mvc-solution-structure.html"&gt;see this post&lt;/a&gt;. (If you read &lt;a href="http://derans.blogspot.com/2010/03/contact-form-with-aspnet-mvc-castle.html"&gt;my first Contact Form post&lt;/a&gt;, you’re probably experiencing déjà vu).&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: #cc7832"&gt;public class &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ContactView
&lt;/span&gt;&lt;span style="color: white"&gt;{
[&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Required&lt;/span&gt;&lt;span style="color: white"&gt;]
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public string &lt;/span&gt;&lt;span style="color: white"&gt;Name { &lt;/span&gt;&lt;span style="color: #cc7832"&gt;get&lt;/span&gt;&lt;span style="color: white"&gt;; &lt;/span&gt;&lt;span style="color: #cc7832"&gt;set&lt;/span&gt;&lt;span style="color: white"&gt;; }
[&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Required&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ValidateEmail&lt;/span&gt;&lt;span style="color: white"&gt;(ErrorMessage = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Valid email is required.&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)]
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public string &lt;/span&gt;&lt;span style="color: white"&gt;Email { &lt;/span&gt;&lt;span style="color: #cc7832"&gt;get&lt;/span&gt;&lt;span style="color: white"&gt;; &lt;/span&gt;&lt;span style="color: #cc7832"&gt;set&lt;/span&gt;&lt;span style="color: white"&gt;; }
[&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Required&lt;/span&gt;&lt;span style="color: white"&gt;]
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public string &lt;/span&gt;&lt;span style="color: white"&gt;Subject { &lt;/span&gt;&lt;span style="color: #cc7832"&gt;get&lt;/span&gt;&lt;span style="color: white"&gt;; &lt;/span&gt;&lt;span style="color: #cc7832"&gt;set&lt;/span&gt;&lt;span style="color: white"&gt;; }
[&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;Required&lt;/span&gt;&lt;span style="color: white"&gt;]
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public string &lt;/span&gt;&lt;span style="color: white"&gt;Message { &lt;/span&gt;&lt;span style="color: #cc7832"&gt;get&lt;/span&gt;&lt;span style="color: white"&gt;; &lt;/span&gt;&lt;span style="color: #cc7832"&gt;set&lt;/span&gt;&lt;span style="color: white"&gt;; }
}
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;The Required attribute is exactly what it seems like and it’s part of the System.ComponentModel.DataAnnotations. The default error message is “The [propertyname] is required.”. If you want to reset it, you can do this: [Required(ErrorMessage = “Whatever I want it to be”)].&lt;/p&gt;&lt;p&gt;The ValidateEmail is a custom validation attribute. I didn’t like the looks of having a RegularExpressionAttribute defined there and since email is such a common thing to validate, I made this one:&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: #cc7832"&gt;public class &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ValidateEmailAttribute &lt;/span&gt;&lt;span style="color: white"&gt;: &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;RegularExpressionAttribute
&lt;/span&gt;&lt;span style="color: white"&gt;{
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public &lt;/span&gt;&lt;span style="color: white"&gt;ValidateEmailAttribute(): &lt;/span&gt;&lt;span style="color: #cc7832"&gt;base&lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #a31515"&gt;@&amp;quot;[a-z0-9!#$%&amp;amp;'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&amp;amp;'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)
{
}
}
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;It just inherits from the RegularExpressionAttribute and passes in the regex to validate an email address. Apparently there is much discussion on how to validate an email address, which I believe is why Microsoft didn’t provide this to us.&lt;/p&gt;&lt;p&gt;So let’s look at the View/XHTML Markup.&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="background: black; color: #6897bb"&gt;@model &lt;/span&gt;&lt;span style="color: white"&gt;Sample.Core.UI.Model.&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ContactView
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: #cc7832"&gt;using &lt;/span&gt;&lt;span style="color: white"&gt;Sample.Core.UI.Helpers
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: #cc7832"&gt;using &lt;/span&gt;&lt;span style="color: white"&gt;(Html.BeginForm(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Contact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Home&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;FormMethod&lt;/span&gt;&lt;span style="color: white"&gt;.Post, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ id = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;contactform&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;}))
{
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;fieldset&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;legend&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;Contact Us&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;legend&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: white"&gt;
&lt;/span&gt;&lt;span style="color: white"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.LabelFor(f =&amp;gt; f.Name, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Your Name&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.TextBoxFor(f =&amp;gt; f.Name, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ style = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;width: 200px&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, @class=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, accesskey=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;n&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;})
&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.LabelFor(f =&amp;gt; f.Email, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Your Email&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.TextBoxFor(f =&amp;gt; f.Email, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ style = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;width: 200px&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, accesskey = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;e&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;})
&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.LabelFor(f =&amp;gt; f.Subject, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Subject&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.TextBoxFor(f =&amp;gt; f.Subject, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ style = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;width: 200px&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, accesskey = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;p&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;})
&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: white"&gt;    &amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.LabelFor(f =&amp;gt; f.Message, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Message&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;)&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.TextAreaFor(f =&amp;gt; f.Message, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ style = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;width: 350px&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, rows = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;4&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, accesskey = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;c&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;})
&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;p&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.AntiForgeryToken()
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;input &lt;/span&gt;&lt;span style="color: white"&gt;type=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;submit&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;id=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;bContact&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;name=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;bContact&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;value=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Send Message&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;accesskey=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;s&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt; 
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.DivSuccessMessage(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Message sent successfully&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;) 
&lt;/span&gt;&lt;span style="background: black; color: #6897bb"&gt;@&lt;/span&gt;&lt;span style="color: white"&gt;Html.ValidationSummary(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ id = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;contacterror&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;})
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;noscript&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;br &lt;/span&gt;&lt;span style="color: white"&gt;/&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;div &lt;/span&gt;&lt;span style="color: white"&gt;class=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;tip&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;Our contact form may look and act funny because you have JavaScript disabled. For a better experience on thissample.com, please enable JavaScript.&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;div&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;noscript&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;span style="color: white"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;fieldset&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
}
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;You can see at the top of the page I specify my view model. I ‘m also referencing a helper namespace for my DivSuccessMessage extension. Basically all it does is checks the ModelState for errors and for ViewData[“success”] not being null and displays the message specified. After that it’s basically a plain ole HTML form. &lt;/p&gt;&lt;p&gt;Okay, now we have our form built with our view model. Below the end of the XHTML above, I have the following &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; code.&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: white"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script &lt;/span&gt;&lt;span style="color: white"&gt;type=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;text/javascript&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;src=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script &lt;/span&gt;&lt;span style="color: white"&gt;type=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;text/javascript&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;src=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;http://ajax.aspnetcdn.com/ajax/jquery.validate/1.8/jquery.validate.min.js&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script &lt;/span&gt;&lt;span style="color: white"&gt;type=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;text/javascript&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;src=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;http://www.malsup.com/jquery/form/jquery.form.js&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script &lt;/span&gt;&lt;span style="color: white"&gt;language=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;javascript&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;type=&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
$(document).ready(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;() {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;formoptions = { beforeSubmit: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(formData, jqForm, options) {
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'value'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'sending...'&lt;/span&gt;&lt;span style="color: white"&gt;);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;);
}, success: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(data) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(data.status == &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;Success&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;) {
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, data.message);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'.valid'&lt;/span&gt;&lt;span style="color: white"&gt;).removeClass(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'valid'&lt;/span&gt;&lt;span style="color: white"&gt;);
validator.resetForm();
}
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;else &lt;/span&gt;&lt;span style="color: white"&gt;{
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, data.message);
}
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'value'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'Send Message'&lt;/span&gt;&lt;span style="color: white"&gt;);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).removeAttr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;);
}, dataType: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;json&amp;quot;
&lt;/span&gt;&lt;span style="color: white"&gt;};jQuery.validator.messages.required = &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;;
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;validator = $(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactform&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).validate({
submitHandler: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(form) {
$(form).ajaxSubmit(formoptions);
},
invalidHandler: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(e, validator) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;errors = validator.numberOfInvalids();
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(errors) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;message = errors == 1 ? &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'You missed 1 field. It has been highlighted.' &lt;/span&gt;&lt;span style="color: white"&gt;: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'You missed ' &lt;/span&gt;&lt;span style="color: white"&gt;+ errors + &lt;/span&gt;&lt;span style="color: #a5c250"&gt;' fields.  They have been highlighted.'&lt;/span&gt;&lt;span style="color: white"&gt;;
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, message);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
} &lt;/span&gt;&lt;span style="color: #cc7832"&gt;else &lt;/span&gt;&lt;span style="color: white"&gt;{
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
}
},
messages: { Email: { email: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;} },
rules: {
Subject: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
Message: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
Email: { required: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;true&lt;/span&gt;&lt;span style="color: white"&gt;, email: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;true &lt;/span&gt;&lt;span style="color: white"&gt;}
},
errorClass: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;invalid&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
validClass: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;valid&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
errorContainer: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;
&lt;/span&gt;&lt;span style="color: white"&gt;});&lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;showMessage(id, message) {
$(id).html(message);
$(id).show();
}
});
&amp;lt;/&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;script&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Let’s break this down. First section the formOptions:&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;formoptions = { beforeSubmit: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(formData, jqForm, options) {
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'value'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'sending...'&lt;/span&gt;&lt;span style="color: white"&gt;);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;);
}, success: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(data) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(data.status == &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;Success&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;) {
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, data.message);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'.valid'&lt;/span&gt;&lt;span style="color: white"&gt;).removeClass(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'valid'&lt;/span&gt;&lt;span style="color: white"&gt;);
validator.resetForm();
}
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;else &lt;/span&gt;&lt;span style="color: white"&gt;{
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, data.message);
}
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).attr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'value'&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'Send Message'&lt;/span&gt;&lt;span style="color: white"&gt;);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#bContact&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).removeAttr(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;'disabled'&lt;/span&gt;&lt;span style="color: white"&gt;);
}, dataType: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;json&amp;quot;
&lt;/span&gt;&lt;span style="color: white"&gt;};
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This code is used to define all my options for the &lt;a href="http://www.malsup.com/jquery/form/"&gt;jQuery.Form plugin&lt;/a&gt;. What it says is this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;beforeSubmit – Change the button to say “sending…” and disable it &lt;/li&gt;
&lt;li&gt;on success – if the status = “Success” then hide the contacterror div, show the success message, manually remove the valid class from my inputs, and reset the form. Otherwise, hide the success message and show the error message with the message received. Regardless, re-enable my button and make it say “Send Message”. (Note: I shouldn’t have to manually remove the valid class, but the resetForm wouldn’t do it for me like it’s supposed to do.) &lt;/li&gt;
&lt;li&gt;dataType – json received from my action &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The validation section:&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: white"&gt;jQuery.validator.messages.required = &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;;
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;validator = $(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactform&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).validate({
submitHandler: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(form) {
$(form).ajaxSubmit(formoptions);
},
invalidHandler: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;(e, validator) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;errors = validator.numberOfInvalids();
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(errors) {
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;message = errors == 1 ? &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'You missed 1 field. It has been highlighted.' &lt;/span&gt;&lt;span style="color: white"&gt;: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;'You missed ' &lt;/span&gt;&lt;span style="color: white"&gt;+ errors + &lt;/span&gt;&lt;span style="color: #a5c250"&gt;' fields.  They have been highlighted.'&lt;/span&gt;&lt;span style="color: white"&gt;;
showMessage(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, message);
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contactsuccess&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
} &lt;/span&gt;&lt;span style="color: #cc7832"&gt;else &lt;/span&gt;&lt;span style="color: white"&gt;{
$(&lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;).hide();
}
},
messages: { Email: { email: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;} },
rules: {
Subject: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
Message: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
Email: { required: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;true&lt;/span&gt;&lt;span style="color: white"&gt;, email: &lt;/span&gt;&lt;span style="color: #cc7832"&gt;true &lt;/span&gt;&lt;span style="color: white"&gt;}
},
errorClass: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;invalid&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
validClass: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;valid&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;,
errorContainer: &lt;/span&gt;&lt;span style="color: #a5c250"&gt;&amp;quot;#contacterror&amp;quot;
&lt;/span&gt;&lt;span style="color: white"&gt;});
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This code defines my &lt;a href="http://docs.jquery.com/Plugins/validation"&gt;validation&lt;/a&gt; for the contact form. It says this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Set all messages for required fields to empty by default &lt;/li&gt;
&lt;li&gt;submitHandler – on submit do this, which it calls the ajaxSubmit contained in the &lt;a href="http://www.malsup.com/jquery/form/"&gt;jQuery.Form plugin&lt;/a&gt; with our options specified above. &lt;/li&gt;
&lt;li&gt;invalidHandler – if the form isn’t valid, get the number of errors and show the error message. Otherwise, hide the error message. &lt;/li&gt;
&lt;li&gt;messages – Defines what the message should be for email, which is empty. I would’ve had to specify the required messages too had I not set them to empty first. Also note that the Email: has to match the ID of one of&amp;#160; your inputs. &lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Example: &amp;lt;input type=”text” id=”whateverid”/&amp;gt; so the messages would looks like this: &lt;br /&gt;
&lt;br /&gt;
messages: {whateverid: {required: “some message”}} &lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;rules – Defines the rules for each input. Phone, Comments are required and Email has required and email. Notice name is required, but not specified here. It’s because I added the required class to the Name input in the XHTML instead of specifying down here so you could see you have options. &lt;/li&gt;
&lt;li&gt;errorClass – Specifies my style class for when the input is invalid. &lt;/li&gt;
&lt;li&gt;validClass – Specifies my style class for when the input is valid. &lt;/li&gt;
&lt;li&gt;errorContainer – Specifies the div I want to show my error messages in. &lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Final section:&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: #cc7832"&gt;function &lt;/span&gt;&lt;span style="color: white"&gt;showMessage(id, message) {
$(id).html(message);
$(id).show();
}
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;This just finds the container sets the html and shows it.&lt;/p&gt;&lt;p&gt;Okay, so finally here’s what the controller looks like that we mentioned in the @Html.BeginForm() section above.&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;&lt;span style="color: white"&gt;[&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;HttpPost&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ValidateAntiForgeryToken&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ValidateInput&lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;true&lt;/span&gt;&lt;span style="color: white"&gt;)]
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;public &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ActionResult &lt;/span&gt;&lt;span style="color: white"&gt;Contact(&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;ContactView &lt;/span&gt;&lt;span style="color: white"&gt;view)
{
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(!ModelState.IsValid)
{
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(Request.IsAjaxRequest())
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;return &lt;/span&gt;&lt;span style="color: white"&gt;Json(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{ status = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, message = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;All fields are required.&amp;quot; &lt;/span&gt;&lt;span style="color: white"&gt;});

&lt;/span&gt;&lt;span style="color: #cc7832"&gt;return &lt;/span&gt;&lt;span style="color: red"&gt;View&lt;/span&gt;&lt;span style="color: white"&gt;(view);
}    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;try
&lt;/span&gt;&lt;span style="color: white"&gt;{
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;notificationService = &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;DI.&lt;font color="#ffffff"&gt;EmailNotificationService&lt;/font&gt;&lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;EmailNotification&lt;/span&gt;&lt;span style="color: white"&gt;(view));
notificationService.Notify();
}
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;catch &lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;NotificationException&lt;/span&gt;&lt;span style="color: white"&gt;)
{
ModelState.AddModelError(&lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;notifyerror&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Could not connect to mail server.&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;);
}    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(Request.IsAjaxRequest())
&lt;/span&gt;&lt;span style="color: #cc7832"&gt;return &lt;/span&gt;&lt;span style="color: white"&gt;ModelState.IsValid ? Json(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{status = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Success&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, message = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Message sent successfully.&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;}) : Json(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: white"&gt;{status = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;, message = &lt;/span&gt;&lt;span style="color: #a5c25c"&gt;&amp;quot;Could not connect to mail server.&amp;quot;&lt;/span&gt;&lt;span style="color: white"&gt;});    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;return &lt;/span&gt;&lt;span style="color: white"&gt;ModelState.IsValid ? Success(view) : &lt;/span&gt;&lt;span style="color: red"&gt;View&lt;/span&gt;&lt;span style="color: white"&gt;(view);
}
&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;So this action accepts HttpPost, must have a valid Anti-Forgery Token, and it validates the input. First thing it does is verifies the modelstate is valid. The reason for this is that some people run their browser with JavaScript disabled. So we have to account for that in our code and make sure that we are validating on the client-side and on the server-side. So if the ModelState is invalid, we have to check to see if it’s an AJAX request. if it is, we return a Json result with the status of error and a message stating all fields are required. If it’s not an AJAX request, we simply return the view. &lt;/p&gt;&lt;p&gt;If all is valid, we continue and go ahead and send the notification. If the notification bombs, we add an error to the modelstate and then recheck and act accordingly. If you want to know what the notification service looks like, please refer to the &lt;a href="http://derans.blogspot.com/2010/03/contact-form-with-aspnet-mvc-castle.html"&gt;first post&lt;/a&gt; because it’s all the exact same.&lt;/p&gt;&lt;p&gt;So, this method of coding will work when JavaScript is enabled and disabled and all the data will be validated regardless as well.&lt;/p&gt;&lt;p&gt;Here’s what the screen looks like after just hitting Send Message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/__ecSVbQQ0Lo/TddIAoUs_iI/AAAAAAAAASE/WjHWPF97GzU/s1600-h/image%5B13%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/__ecSVbQQ0Lo/TddIBOVIqXI/AAAAAAAAASI/IoSaiG8AWPc/image_thumb%5B7%5D.png?imgmax=800" width="598" height="367" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Here’s what it looks like after all the fields are valid right before I hit Send Message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/__ecSVbQQ0Lo/TddIBQqnlMI/AAAAAAAAASM/agMTaD6-ODo/s1600-h/image%5B8%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/__ecSVbQQ0Lo/TddIB9w7zkI/AAAAAAAAASQ/HLgR42LnoqY/image_thumb%5B4%5D.png?imgmax=800" width="405" height="393" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;After message sent:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/__ecSVbQQ0Lo/TddICPta0NI/AAAAAAAAASU/IQqJ-VzMU_s/s1600-h/image%5B12%5D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/__ecSVbQQ0Lo/TddICf4tlzI/AAAAAAAAASY/8oZjtCGpGQo/image_thumb%5B6%5D.png?imgmax=800" width="537" height="324" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Please let me know if you have any questions.&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/derans/downloads/detail?name=ContactFormExample.zip"&gt;Download Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;&lt;a rev="vote-for" href="http://dotnetshoutout.com/Contact-Form-Revisited-with-ASPNET-MVC-3-jQuery-Validator-the-jQuery-Form-Plugin"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fderans.blogspot.com%2F2011%2F05%2Fcontact-form-revisited-with-aspnet-mvc.html" style="border:0px"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-8823321394358027303?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=z80QrfQw8Ec:v4XbjxUMStc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=z80QrfQw8Ec:v4XbjxUMStc:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=z80QrfQw8Ec:v4XbjxUMStc:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/z80QrfQw8Ec" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/8823321394358027303/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=8823321394358027303" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/8823321394358027303?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/8823321394358027303?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/z80QrfQw8Ec/contact-form-revisited-with-aspnet-mvc.html" title="Contact Form Revisited with ASP.NET MVC 3, jQuery Validator, &amp;amp; the jQuery Form Plugin" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/__ecSVbQQ0Lo/TddIBOVIqXI/AAAAAAAAASI/IoSaiG8AWPc/s72-c/image_thumb%5B7%5D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/05/contact-form-revisited-with-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQHSH45cSp7ImA9WhZWEE0.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-4077504850492339625</id><published>2011-05-09T23:16:00.006-05:00</published><updated>2011-05-09T23:55:39.029-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-09T23:55:39.029-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="WebFormContrib" /><category scheme="http://www.blogger.com/atom/ns#" term="TDD" /><title>Seriously WebForms like ASP.NET MVC</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:0px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;I used my little WebFormContrib library again today. Some days I love revisiting old code because you realize how ignorant of some practices you were in the past. Hopefully none of you download it and say…geez this guy &lt;em&gt;is &lt;/em&gt;Mr. Ignoramus. If you do, keep it to yourself. Kidding, please comment and inform the ignorant (me).&lt;/p&gt;  &lt;p&gt;Anyhow, it’s been about 6 months since I’ve had to use WebForms, but today I had to and it wasn’t bad. I was able to tie my view into my pages and controls and used &lt;a href="http://automapper.codeplex.com/"&gt;AutoMapper&lt;/a&gt; to map back to the domain from it. To me, WebFormContrib makes WebForms kinda fun again…cause it makes it seem new. I really do think it’s a great stepping stone to using MVC just because you kinda get used to the syntax. I also think it’s a decent library because I didn’t have to go relearn how it worked, I just referenced the library and then started working on my little WebForm app. I set it up just like I do my MVC apps. I also had to add a couple things and it was easily extendable, which I’m sure you all know is a good thing.&lt;/p&gt;  &lt;p&gt;Anyhow, if you have no idea what I’m talking about, please read my previous posts on WebFormContrib.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://derans.blogspot.com/2010/11/webformcontrib-web-forms-more-like.html"&gt;The Original – WebFormContrib – Web Forms more like ASP.NET MVC&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://derans.blogspot.com/2010/12/webformcontrib-sample-part-1.html"&gt;WebFormContrib – Sample Part 1&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://derans.blogspot.com/2010/12/webformcontrib-sample-part-2.html"&gt;WebFormContrib – Sample Part 2&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://derans.blogspot.com/2010/12/webformcontrib-sample-part-3.html"&gt;WebFormContrib – Sample Part 3&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Also, how could I post without a code sample? In “The Original” post, I mentioned the first thing I wanted to refactor was the validation section. Well, I did. Here’s the new and improved ModelIsValid() method:&lt;/p&gt;  &lt;pre style="background: #000" class="code"&gt;        &lt;span style="color: #cc7832"&gt;internal bool &lt;/span&gt;&lt;span style="color: white"&gt;ModelIsValid(TModel view)&lt;br /&gt;        {&lt;br /&gt;            ErrorMessages = &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;List&lt;/span&gt;&lt;span style="color: white"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #cc7832"&gt;string&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;();&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #cc7832"&gt;foreach &lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;property &lt;/span&gt;&lt;span style="color: #cc7832"&gt;in typeof&lt;/span&gt;&lt;span style="color: white"&gt;(TModel).GetProperties())&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;value = property.GetValue(view, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;null&lt;/span&gt;&lt;span style="color: white"&gt;);&lt;br /&gt;&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;attributes = property.GetCustomAttributes(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #2b91af"&gt;IValidationAttribute&lt;/span&gt;&lt;span style="color: white"&gt;), &lt;/span&gt;&lt;span style="color: #cc7832"&gt;false&lt;/span&gt;&lt;span style="color: white"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;foreach &lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #2b91af"&gt;IValidationAttribute &lt;/span&gt;&lt;span style="color: white"&gt;valatt &lt;/span&gt;&lt;span style="color: #cc7832"&gt;in &lt;/span&gt;&lt;span style="color: white"&gt;attributes)&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(!valatt.IsValid(value))&lt;br /&gt;                        ErrorMessages.Add(valatt.Message);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #cc7832"&gt;return &lt;/span&gt;&lt;span style="color: white"&gt;ErrorMessages.Count == 0;&lt;br /&gt;        }&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Previously, it looked like this:&lt;/p&gt;&lt;pre style="background: #000" class="code"&gt;        &lt;span style="color: #cc7832"&gt;internal bool &lt;/span&gt;&lt;span style="color: white"&gt;ModelIsValid(TModel view)&lt;br /&gt;        {&lt;br /&gt;            ErrorMessages = &lt;/span&gt;&lt;span style="color: #cc7832"&gt;new &lt;/span&gt;&lt;span style="color: #ffc66d"&gt;List&lt;/span&gt;&lt;span style="color: white"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #cc7832"&gt;string&lt;/span&gt;&lt;span style="color: white"&gt;&amp;gt;();&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #cc7832"&gt;foreach &lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;property &lt;/span&gt;&lt;span style="color: #cc7832"&gt;in typeof&lt;/span&gt;&lt;span style="color: white"&gt;(TModel).GetProperties())&lt;br /&gt;            {&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;attributes = property.GetCustomAttributes(&lt;/span&gt;&lt;span style="color: #cc7832"&gt;typeof&lt;/span&gt;&lt;span style="color: white"&gt;(&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;RequiredAttribute&lt;/span&gt;&lt;span style="color: white"&gt;), &lt;/span&gt;&lt;span style="color: #cc7832"&gt;false&lt;/span&gt;&lt;span style="color: white"&gt;);&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(attributes.Length &amp;gt; 0)&lt;br /&gt;                {&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;var &lt;/span&gt;&lt;span style="color: white"&gt;value = property.GetValue(view, &lt;/span&gt;&lt;span style="color: #cc7832"&gt;null&lt;/span&gt;&lt;span style="color: white"&gt;);&lt;br /&gt;                    &lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(value.ToSafeString() == &lt;/span&gt;&lt;span style="color: #cc7832"&gt;string&lt;/span&gt;&lt;span style="color: white"&gt;.Empty)&lt;br /&gt;                        ErrorMessages.Add(((&lt;/span&gt;&lt;span style="color: #ffc66d"&gt;RequiredAttribute&lt;/span&gt;&lt;span style="color: white"&gt;)attributes[0]).Message);&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #cc7832"&gt;if &lt;/span&gt;&lt;span style="color: white"&gt;(ErrorMessages.Count == 0)&lt;br /&gt;                &lt;/span&gt;&lt;span style="color: #cc7832"&gt;return true&lt;/span&gt;&lt;span style="color: white"&gt;;&lt;br /&gt;&lt;br /&gt;            &lt;/span&gt;&lt;span style="color: #cc7832"&gt;return false&lt;/span&gt;&lt;span style="color: white"&gt;;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;&lt;p&gt;Obviously…I was a moron. I still don’t think it’s perfect, but it is a serious improvement. It’s funny how you don’t see how to refactor something until you need to extend it. As soon as I created the length validator and added the code here I thought…wow this is dumb and then OH! do it this way. Anyhow, I thought I’d share the slight improvement.&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/derans/downloads/detail?name=WebFormContrib_v1.2.zip"&gt;You can download the source and samples here&lt;/a&gt;…or &lt;a href="http://code.google.com/p/derans/downloads/detail?name=WebFormContrib.dll"&gt;just download the DLL here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;a rev="vote-for" href="http://dotnetshoutout.com/Seriously-WebForms-like-ASPNET-MVC"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fderans.blogspot.com%2F2011%2F05%2Fseriously-webforms-like-aspnet-mvc.html" style="border:0px"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-4077504850492339625?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=qxxCUvLqDfg:0Bl-CbFG0hs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=qxxCUvLqDfg:0Bl-CbFG0hs:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=qxxCUvLqDfg:0Bl-CbFG0hs:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/qxxCUvLqDfg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/4077504850492339625/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=4077504850492339625" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/4077504850492339625?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/4077504850492339625?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/qxxCUvLqDfg/seriously-webforms-like-aspnet-mvc.html" title="Seriously WebForms like ASP.NET MVC" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/05/seriously-webforms-like-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YEQXY4eCp7ImA9WhZRGEk.&quot;"><id>tag:blogger.com,1999:blog-19251193.post-7612693785972880441</id><published>2011-04-15T01:27:00.003-05:00</published><updated>2011-04-15T01:31:40.830-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-15T01:31:40.830-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="visual studio" /><category scheme="http://www.blogger.com/atom/ns#" term="AutoMapper" /><category scheme="http://www.blogger.com/atom/ns#" term="flickr" /><category scheme="http://www.blogger.com/atom/ns#" term="StructureMap" /><category scheme="http://www.blogger.com/atom/ns#" term="mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="ASP.NET" /><category scheme="http://www.blogger.com/atom/ns#" term="moq" /><category scheme="http://www.blogger.com/atom/ns#" term="FluentHtml" /><title>ASP.NET MVC 3 Sample Project Launched</title><content type="html">&lt;div class="wlWriterHeaderFooter" style="float:right; margin:0 20px; padding:0px 0px 0px 0px;"&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;tweetmeme_source = 'derans';&lt;br /&gt;tweetmeme_service = 'is.gd';&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;Okay, after popular demand of I think 0 people, I’ve published my old demo MVC 1 project as an MVC 3 project. If you haven’t read any of the posts on the last demo project, check out &lt;a href="http://derans.blogspot.com/2010/01/aspnet-mvc-sample-project-launched.html"&gt;this post&lt;/a&gt;. This project completely separates UI &amp;amp; C# code, so you only have 2 projects (Core &amp;amp; UI…not counting the Unit Tests project). &lt;/p&gt;  &lt;p&gt;Basically, all I did was create a new MVC 3 project using Razor with Microsoft’s default template and deleted everything &lt;strong&gt;except &lt;/strong&gt;the following:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Views folder &lt;/li&gt;    &lt;li&gt;Root Default.aspx &lt;/li&gt;    &lt;li&gt;global.asax (I did delete the global.asax.cs) &lt;/li&gt;    &lt;li&gt;both web.configs&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I referenced my Core, setup my views that match my Core project, and inherited from my global.cs in the global.asax. That was it!&lt;/p&gt;  &lt;p&gt;You can download it via zip here: &lt;a href="http://code.google.com/p/derans/downloads/list"&gt;http://code.google.com/p/derans/downloads/list&lt;/a&gt; (the file is called DemoPhotographySite_v3.zip)&lt;/p&gt;  &lt;p&gt;I feel like this project will act as a great stepping stone to understanding the Code Camp server, which is much more complex.&lt;/p&gt;  &lt;p&gt;The sample project was built with the following tools:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://structuremap.sourceforge.net/"&gt;StructureMap&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://automapper.codeplex.com/"&gt;AutoMapper&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.codeplex.com/FlickrNet"&gt;FlickrNet&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.nunit.org/"&gt;NUnit&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;If you downloaded the old one, you’ll notice that I removed the following 3rd parties:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://mvccontrib.codeplex.com/"&gt;MvcContrib&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;a href="http://mvccontrib.codeplex.com/"&gt;MvcContrib.FluentHtml&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.castleproject.org/components/validator/index.html"&gt;Castle.Components.Validator&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The primary reason I removed these three parties is because MVC 3 and Razor are good enough so you don’t need the 3rd party tools.&lt;/p&gt;  &lt;p&gt;The best practices I mentioned above come straight from experience and the following people/resources:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/"&gt;Scott Guthrie&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.manning.com/palermo/"&gt;ASP.NET MVC in Action&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://codecampserver.googlecode.com/"&gt;Code Camp Server&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.lostechies.com/blogs/jimmy_bogard/default.aspx"&gt;Jimmy Bogard&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://jeffreypalermo.com/"&gt;Jeffrey Palermo&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://www.wekeroad.com/"&gt;Rob Conery&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can see the exact same Core code in use at &lt;a href="http://sweetandhappy.com/"&gt;sweetandhappy.com&lt;/a&gt;. If you see any improvements that can be made or you’d just like to comment, please do so! &lt;/p&gt;  &lt;p&gt;Also, please note that I basically am even re-posting the exact same blog post I did over a year ago with my original MVC demo project. I hope you don’t mind, but it’s late and I have to work tomorrow :)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Thanks for reading!&lt;/strong&gt;&lt;/p&gt;  &lt;a rev="vote-for" href="http://dotnetshoutout.com/ASPNET-MVC-3-Sample-Project-Launched"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fderans.blogspot.com%2F2011%2F04%2Faspnet-mvc-3-sample-project-launched.html" style="border:0px"/&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19251193-7612693785972880441?l=derans.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/derans?a=tXMoAVPDgsk:2LsrvSDKNk8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/derans?a=tXMoAVPDgsk:2LsrvSDKNk8:1SkO2fh7a-Q"&gt;&lt;img src="http://feeds.feedburner.com/~ff/derans?i=tXMoAVPDgsk:2LsrvSDKNk8:1SkO2fh7a-Q" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/derans/~4/tXMoAVPDgsk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://derans.blogspot.com/feeds/7612693785972880441/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=19251193&amp;postID=7612693785972880441" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/7612693785972880441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/19251193/posts/default/7612693785972880441?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/derans/~3/tXMoAVPDgsk/aspnet-mvc-3-sample-project-launched.html" title="ASP.NET MVC 3 Sample Project Launched" /><author><name>Deran Schilling</name><uri>http://www.blogger.com/profile/06750574925211298370</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="25" src="http://3.bp.blogspot.com/__ecSVbQQ0Lo/SfaCJd8pHzI/AAAAAAAAAD4/ECd5Dxgb1iM/S220/me2.png" /></author><thr:total>0</thr:total><feedburner:origLink>http://derans.blogspot.com/2011/04/aspnet-mvc-3-sample-project-launched.html</feedburner:origLink></entry></feed>

