<?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:blogger="http://schemas.google.com/blogger/2008" 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;D04NSH49cSp7ImA9WhBbGEo.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594</id><updated>2013-05-18T04:19:59.069-07:00</updated><category term="wcf" /><category term="LINQ" /><category term="technology" /><category term="jQuery" /><category term="MySQL" /><category term="SQL" /><category term="TFS" /><category term="bug fixes" /><category term="windows azure" /><category term="unit testing" /><category term="asp.net" /><category term="google charts" /><category term="code snippets" /><category term="general" /><category term="church management" /><category term="IIS" /><category term="asp.net mvc" /><title>Schnieds Blog</title><subtitle type="html">Software engineering in .NET</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.schnieds.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.schnieds.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/schnieds/RXSk" /><feedburner:info uri="schnieds/rxsk" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DUIESHc8eyp7ImA9WhdREEg.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4017831360089128533</id><published>2011-07-30T13:24:00.000-07:00</published><updated>2011-07-30T13:25:09.973-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-30T13:25:09.973-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code snippets" /><category scheme="http://www.blogger.com/atom/ns#" term="general" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Image Upload, Crop and Resize with ASP.NET MVC jQuery Uploadify and jCrop</title><content type="html">&lt;p&gt;I need a slick way for my customers to upload, crop and resize photos within my &lt;a href="https://www.churchmembershiponline.com/login.aspx?demo=true" target="_blank"&gt;Church Management Software&lt;/a&gt;. After doing some research it seems that a bunch of existing libraries and utilities need to be combined to create a functional and slick user experience for this seemingly mundane task. Specifically the platform I want to use is ASP.NET MVC (although this code will work equally well in Java with a few changes) and the best tools for uploading and cropping images seem to be &lt;a href="http://www.uploadify.com" target="_blank"&gt;Uploadify&lt;/a&gt; and &lt;a href="http://deepliquid.com/content/Jcrop.html" target="_blank"&gt;jCrop&lt;/a&gt; powered by &lt;a href="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt; (of course.)&lt;/p&gt; &lt;p&gt;I found a lot of examples of each different library used in ASP.NET (and a few in MVC) but the examples where rather simplistic and didn’t really provide an elegant end to end solution tying together these great libraries. So I went ahead and created a nice ASP.NET MVC based sample application that accomplishes the following…&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Uploads images with Uploadify  &lt;li&gt;Stores uploaded images in Cache  &lt;li&gt;Crops images using jCrop  &lt;li&gt;Resizing images  &lt;li&gt;All interactions handled by jQuery AJAX for a smooth UX&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;&lt;a href="http://lh4.ggpht.com/-MKuoO6l9VLA/TjRooo7t9BI/AAAAAAAAAI8/RgZY_WoyplM/s1600-h/image%25255B10%25255D.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://lh3.ggpht.com/-LmmScE42p4w/TjRopL9GHLI/AAAAAAAAAJA/GT3sJXFCLjM/image_thumb%25255B6%25255D.png?imgmax=800" width="537" height="479"&gt;&lt;/a&gt;&lt;/p&gt; &lt;h2&gt;Uploading Images&lt;/h2&gt; &lt;p&gt;I used a &lt;a href="http://zootfroot.blogspot.com/2010/12/mvc-file-upload-using-uploadify-with.html" target="_blank"&gt;great blog post by James McCormack&lt;/a&gt; as the base for uploading images with Uploadify and ASP.NET MVC. Basically Uploadify is doing the heavy lifting and I just tied the onComplete event to an ASP.NET MVC Controller method.&lt;/p&gt; &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;$(&lt;span style="color: #006080"&gt;"#fuFileUploader"&lt;/span&gt;).uploadify({&lt;br&gt;                &lt;span style="color: #006080"&gt;'hideButton'&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,       &lt;span style="color: #008000"&gt;// We use a trick below to overlay a fake html upload button with this hidden flash button                         &lt;/span&gt;&lt;br&gt;                &lt;span style="color: #006080"&gt;'wmode'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'transparent'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'uploader'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'&amp;lt;%= Url.Content("~/Uploadify/uploadify.swf") %&amp;gt;'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'cancelImg'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'&amp;lt;%= Url.Content("~/Uploadify/cancel.png") %&amp;gt;'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'buttonText'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'Upload File'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'script'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'&amp;lt;%= Url.Action("FileUpload", "Media") %&amp;gt;'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'multi'&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'auto'&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'fileExt'&lt;/span&gt;: &lt;span style="color: #006080"&gt;'*.jpg;*.gif;*.png;*.jpeg'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'fileDesc'&lt;/span&gt; : &lt;span style="color: #006080"&gt;'Image Files'&lt;/span&gt;,&lt;br&gt;                &lt;span style="color: #006080"&gt;'scriptData'&lt;/span&gt;: { RequireUploadifySessionSync: &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, SecurityToken: UploadifyAuthCookie, SessionId: UploadifySessionId },&lt;br&gt;                &lt;span style="color: #006080"&gt;'onComplete'&lt;/span&gt;: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;event&lt;/span&gt;, ID, fileObj, response, data) {&lt;br&gt;                    response = $.parseJSON(response);&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (response.Status == &lt;span style="color: #006080"&gt;'OK'&lt;/span&gt;) {&lt;br&gt;                        $(&lt;span style="color: #006080"&gt;"#pnlUpload"&lt;/span&gt;).hide();&lt;br&gt;                        $(&lt;span style="color: #006080"&gt;"#pnlUploadedImage"&lt;/span&gt;).show();&lt;br&gt;                        $(&lt;span style="color: #006080"&gt;"#imgUploadedImage"&lt;/span&gt;).attr(&lt;span style="color: #006080"&gt;"src"&lt;/span&gt;, imageHandler + response.Id);&lt;br&gt;                        $(&lt;span style="color: #006080"&gt;'#imgUploadedImage'&lt;/span&gt;).Jcrop({&lt;br&gt;                            onChange: setCoords,&lt;br&gt;                            onSelect: setCoords&lt;br&gt;                        });&lt;br&gt;                    }&lt;br&gt;                }&lt;br&gt;            });&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The controller method grabs the image that was uploaded…&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; ActionResult FileUpload(MediaAssetUploadModel uploadedFileMeta)&lt;br&gt;        {&lt;br&gt;            Guid newImageId = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Guid();&lt;br&gt;            &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br&gt;            {&lt;br&gt;                newImageId = ProcessUploadedImage(uploadedFileMeta);&lt;br&gt;            }&lt;br&gt;            &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; errorMsg = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"Error processing image: {0}"&lt;/span&gt;, ex.Message);&lt;br&gt;                Response.StatusCode = 500;&lt;br&gt;                Response.Write(errorMsg);&lt;br&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; { Id = newImageId, Status = &lt;span style="color: #006080"&gt;"OK"&lt;/span&gt; });&lt;br&gt;        }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And then processes it….&lt;/p&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; Guid ProcessUploadedImage(MediaAssetUploadModel uploadedFileMeta)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: #008000"&gt;// Get the file extension&lt;/span&gt;&lt;br&gt;            WorkingImageExtension = Path.GetExtension(uploadedFileMeta.Filename).ToLower();&lt;br&gt;            &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;[] allowedExtensions = { &lt;span style="color: #006080"&gt;".png"&lt;/span&gt;, &lt;span style="color: #006080"&gt;".jpeg"&lt;/span&gt;, &lt;span style="color: #006080"&gt;".jpg"&lt;/span&gt;, &lt;span style="color: #006080"&gt;".gif"&lt;/span&gt; }; &lt;span style="color: #008000"&gt;// Make sure it is an image that can be processed&lt;/span&gt;&lt;br&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (allowedExtensions.Contains(WorkingImageExtension))&lt;br&gt;            {&lt;br&gt;                WorkingImageId = Guid.NewGuid();&lt;br&gt;                Image workingImage = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Bitmap(uploadedFileMeta.fileData.InputStream);&lt;br&gt;                WorkingImage = ImageHelper.ImageToByteArray(workingImage);&lt;br&gt;            }&lt;br&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Exception(&lt;span style="color: #006080"&gt;"Cannot process files of this type."&lt;/span&gt;);&lt;br&gt;            }&lt;br&gt;&lt;br&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; WorkingImageId;&lt;br&gt;        }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;And stores the image converted to a byte array in Cache…&lt;/p&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: 'Courier New', courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #cc6633"&gt;#region&lt;/span&gt; cached properties&lt;br&gt;&lt;br&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] WorkingImage&lt;br&gt;        {&lt;br&gt;            get&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] img = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br&gt;&lt;br&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (HttpContext.Cache[WorkingImageCacheKey] != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br&gt;                    img = (&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[])HttpContext.Cache[WorkingImageCacheKey];&lt;br&gt;&lt;br&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; img;&lt;br&gt;            }&lt;br&gt;            set&lt;br&gt;            {&lt;br&gt;                HttpContext.Cache.Add(WorkingImageCacheKey,&lt;br&gt;                  &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;,&lt;br&gt;                  &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,&lt;br&gt;                  System.Web.Caching.Cache.NoAbsoluteExpiration,&lt;br&gt;                  &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 40, 0),&lt;br&gt;                  System.Web.Caching.CacheItemPriority.Low,&lt;br&gt;                  &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] ModifiedImage&lt;br&gt;        {&lt;br&gt;            get&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] img = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (HttpContext.Cache[ModifiedImageCacheKey] != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br&gt;                    img = (&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[])HttpContext.Cache[ModifiedImageCacheKey];&lt;br&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; img;&lt;br&gt;            }&lt;br&gt;            set&lt;br&gt;            {&lt;br&gt;                HttpContext.Cache.Add(ModifiedImageCacheKey,&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;,&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;,&lt;br&gt;                    System.Web.Caching.Cache.NoAbsoluteExpiration,&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; TimeSpan(0, 40, 0),&lt;br&gt;                    System.Web.Caching.CacheItemPriority.Low,&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;);&lt;br&gt;            }&lt;br&gt;        }&lt;br&gt;&lt;br&gt;        &lt;span style="color: #cc6633"&gt;#endregion&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The image is assigned in id, which is used as the Cache key and is returned back out via json. Once the call is successfully completed an img src attribute is updated to point to a ASHX image handler I wrote that accepts the id as a querystring parameter.&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;$(&lt;span style="color: #006080"&gt;"#imgUploadedImage"&lt;/span&gt;).attr(&lt;span style="color: #006080"&gt;"src"&lt;/span&gt;, imageHandler + response.Id);&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The image handler grabs the image out of the cache and then displays it.&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; ProcessRequest (HttpContext context) {&lt;br&gt;        &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] image = GetImage(context.Request.QueryString[&lt;span style="color: #006080"&gt;"id"&lt;/span&gt;], context);&lt;br&gt;        context.Response.Clear();&lt;br&gt;        context.Response.ContentType = &lt;span style="color: #006080"&gt;"image/pjpeg"&lt;/span&gt;;&lt;br&gt;        context.Response.BinaryWrite(image);&lt;br&gt;        context.Response.End();&lt;br&gt;    }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Cropping Images&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Once the image has been uploaded, jCrop is initialized to allow for image crop selection.&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;$(&lt;span style="color: #006080"&gt;'#imgUploadedImage'&lt;/span&gt;).Jcrop({&lt;br&gt;                            onChange: setCoords,&lt;br&gt;                            onSelect: setCoords&lt;br&gt;                        });&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;If the user selects a region to crop and clicks the crop button a jQuery AJAX call is made to the server. The x, y and width, height crop values are posted to the server and then the server crops the image as specified. A new modified image id is returned via json to the view and then the new cropped image is displayed via the image handler ashx once again.&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; cropImage() {&lt;br&gt;            $.ajax({&lt;br&gt;                url: &lt;span style="color: #006080"&gt;"/Media/CropImage"&lt;/span&gt;,&lt;br&gt;                type: &lt;span style="color: #006080"&gt;"POST"&lt;/span&gt;,&lt;br&gt;                data: { x: x, y: y, w: w, h: h },&lt;br&gt;                success: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (data) {&lt;br&gt;                    $(&lt;span style="color: #006080"&gt;'#lblMethodError'&lt;/span&gt;).hide();&lt;br&gt;                    $(&lt;span style="color: #006080"&gt;"#pnlNewImage"&lt;/span&gt;).show();&lt;br&gt;                    $(&lt;span style="color: #006080"&gt;"#imgNewImage"&lt;/span&gt;).attr(&lt;span style="color: #006080"&gt;"src"&lt;/span&gt;, imageHandler + data);&lt;br&gt;                },&lt;br&gt;                error: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt; (xhr, status, error) {&lt;br&gt;                    &lt;span style="color: #008000"&gt;// Show the error&lt;/span&gt;&lt;br&gt;                    $(&lt;span style="color: #006080"&gt;'#lblMethodError'&lt;/span&gt;).text(xhr.responseText);&lt;br&gt;                    $(&lt;span style="color: #006080"&gt;'#lblMethodError'&lt;/span&gt;).show();&lt;br&gt;                }&lt;br&gt;            });&lt;br&gt;                    &lt;br&gt;        }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; JsonResult CropImage(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; y, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; w, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; h)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: #0000ff"&gt;try&lt;/span&gt;&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (w == 0 &amp;amp;&amp;amp; h == 0) &lt;span style="color: #008000"&gt;// Make sure the user selected a crop area&lt;/span&gt;&lt;br&gt;                    &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Exception(&lt;span style="color: #006080"&gt;"A crop selection was not made."&lt;/span&gt;);&lt;br&gt;&lt;br&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; imageId = ModifyImage(x, y, w, h, ImageModificationType.Crop);&lt;br&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(imageId);&lt;br&gt;            }&lt;br&gt;            &lt;span style="color: #0000ff"&gt;catch&lt;/span&gt; (Exception ex)&lt;br&gt;            {&lt;br&gt;                &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; errorMsg = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&lt;span style="color: #006080"&gt;"Error cropping image: {0}"&lt;/span&gt;, ex.Message);&lt;br&gt;                Response.StatusCode = 500;&lt;br&gt;                Response.Write(errorMsg);&lt;br&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Json(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty);&lt;br&gt;            }&lt;br&gt;        }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Resizing Images&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;Resizing images follows the same basic pattern. I have hard coded the new image dimensions in the example, but you could easily add a couple of inputs to the view and allow the user to specify the new dimensions.&lt;/p&gt;&lt;br /&gt;&lt;h2&gt;Download the Example&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;I put together a full working example that includes all of the code above and is the basis for what I will end up implemented in my SaaS. I hope you find this helpful.&lt;/p&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="https://skydrive.live.com/embedicon.aspx/Public/ImageUploadAndCrop.zip?cid=a62623415e09df8d&amp;amp;sc=documents" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;p&gt;Aaron Schnieder&lt;br&gt;&lt;a href="http://www.churchofficeonline.com" target="_blank"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/OyyRpLYd7PY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4017831360089128533/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4017831360089128533" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4017831360089128533?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4017831360089128533?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/OyyRpLYd7PY/image-upload-crop-and-resize-with.html" title="Image Upload, Crop and Resize with ASP.NET MVC jQuery Uploadify and jCrop" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh3.ggpht.com/-LmmScE42p4w/TjRopL9GHLI/AAAAAAAAAJA/GT3sJXFCLjM/s72-c/image_thumb%25255B6%25255D.png?imgmax=800" height="72" width="72" /><thr:total>12</thr:total><feedburner:origLink>http://www.schnieds.com/2011/07/image-upload-crop-and-resize-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkENRXc-fyp7ImA9Wx9SEUU.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-3436967842939908693</id><published>2010-11-30T19:23:00.000-08:00</published><updated>2010-11-30T23:31:34.957-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-30T23:31:34.957-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="windows azure" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><title>Azure SDK 1.3 Beta - System.ServiceModel Exception on Debug</title><content type="html">I started using the new Windows Azure 1.3 SDK (BETA) yesterday and after I installed it I began getting a strange error when I tried to run Debug from Visual Studio 2010.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
System.ServiceModel.CommunicationObjectFaultedException was unhandled&lt;br /&gt;
Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.&lt;br /&gt;
&lt;br /&gt;
This issue drove me crazy for the last day and after much weeping and gnashing of teeth, I figured out what the fix is:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Make sure your web role web.config is writable&lt;/b&gt; (i.e. not locked in read-only by source control or the read-only file bit.)&lt;br /&gt;
&lt;br /&gt;
It looks like there is a bug in the Azure SDK 1.3 that is causing the web.config to be written to during the instantiation of the Azure dev fabric roles. If the web.config is read-only, Azure is blocked from editing the file (no actual edits take place that I can find) and the bizarro System.ServiceModel.CommunicationObjectFailedException message bubbles up.&lt;br /&gt;
&lt;br /&gt;
Secondarily.... Make sure that any &lt;system.web&gt;&lt;httpmodule&gt; declarations are moved to &lt;system.webServer&gt;&lt;modules&gt;. This was a minor issue causing a few hiccups (not the main problem), but I thought it was worth mentioning.&lt;br /&gt;
&lt;br /&gt;
Hope that helps everyone.&lt;br /&gt;
&lt;br /&gt;
Aaron&lt;br /&gt;
&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/igUMvzUtsZE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/3436967842939908693/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=3436967842939908693" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3436967842939908693?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3436967842939908693?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/igUMvzUtsZE/azure-sdk-13-beta-systemservicemodel.html" title="Azure SDK 1.3 Beta - System.ServiceModel Exception on Debug" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2010/11/azure-sdk-13-beta-systemservicemodel.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AARXw-fSp7ImA9WxFWFEQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-2817932822542320827</id><published>2010-06-02T09:22:00.001-07:00</published><updated>2010-06-02T09:22:24.255-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T09:22:24.255-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>jQuery AJAX Validation Using The Validity Plugin</title><content type="html">&lt;h3&gt;Books I recommend on this subject&lt;/h3&gt; &lt;p&gt;The following book is the best reference I have found when working with jQuery. I highly recommend it!&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/1933988355?ie=UTF8&amp;amp;tag=aasconasne-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1933988355"&gt;jQuery in Action&lt;/a&gt;&lt;img style="border-bottom-style: none !important; border-right-style: none !important; margin: 0px; border-top-style: none !important; border-left-style: none !important" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=aasconasne-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1933988355" width="1" height="1"&gt; &lt;/p&gt; &lt;h3&gt;jQuery Validity&lt;/h3&gt; &lt;p&gt;Input validation is one of those areas that most developers view as a necessary evil. We know that it is necessary and we really do want to ensure that we get good input from our users. But most of us are lazy (me included) and input validation is one of those things that gets done but usually is a quick and dirty implementation. This is partly due to laziness and partly do to input validation being painful. &lt;/p&gt; &lt;p&gt;Thanks to the amazing jQuery Validity plug in, input validation can be really slick, easy and robust enough to work any any scenario. I specifically like the Validity plugin because it supports jQuery AJAX input validation. Other input validation implementations that I have worked with require a form post to take place. However, if you are using jQuery.ajax methods then there isn’t a form and you need to validate the formless input.&lt;/p&gt; &lt;p&gt;Here is the download link for the jQuery Validity plugin: &lt;a href="http://code.google.com/p/validity/downloads/list"&gt;http://code.google.com/p/validity/downloads/list&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Here is the documentation for the jQuery Validity plugin: &lt;a href="http://validity.thatscaptaintoyou.com/"&gt;http://validity.thatscaptaintoyou.com/&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;What It Looks Like&lt;/h3&gt; &lt;p&gt;The default UI for the validation feedback is pretty nice, take a look:&lt;/p&gt; &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QQqEHtDW18M/TAaFPKmSSaI/AAAAAAAAAIE/eqtNCmBKVFo/s1600-h/jQueryValidityScreenshot4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="jQueryValidityScreenshot" border="0" alt="jQueryValidityScreenshot" src="http://lh6.ggpht.com/_QQqEHtDW18M/TAaFPyMUpnI/AAAAAAAAAII/tURha6OxmH8/jQueryValidityScreenshot_thumb2.png?imgmax=800" width="567" height="318"&gt;&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;HTML Input&lt;/h3&gt; &lt;p&gt;Here is the HTML markup that I used to create the inputs to validate:&lt;/p&gt; &lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;fieldset&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="SignUpFields"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;legend&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Sign Up&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;legend&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Name&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtbxName"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Email&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtbxEmail"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Password&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="password"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtbxPassword"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Confirm Password&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="password"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtbxConfirmPassword"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;How Did You Hear About Us?&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;input&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="text"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="txtbxSource"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;fieldset&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;button&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="btnSubmit"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;button&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;jQuery and Validity Functions&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;The jQuery Validity code is extremely straight forward and minimal.&lt;/p&gt;&lt;br /&gt;&lt;div id="codeSnippetWrapper"&gt;&lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: 'Courier New', courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;$(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {&lt;br&gt;    &lt;span style="color: #008000"&gt;// Handle the click event for the submit button&lt;/span&gt;&lt;br&gt;    $(&lt;span style="color: #006080"&gt;'#btnSubmit'&lt;/span&gt;).click(&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; () {&lt;br&gt;        &lt;span style="color: #008000"&gt;// Validate the fields&lt;/span&gt;&lt;br&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ValidateFields()) {&lt;br&gt;            &lt;span style="color: #008000"&gt;// All fields are valid, $.ajax POST would go here&lt;/span&gt;&lt;br&gt;            $(&lt;span style="color: #006080"&gt;'#SignUpFields'&lt;/span&gt;).hide();&lt;br&gt;            $(&lt;span style="color: #006080"&gt;'#btnSubmit'&lt;/span&gt;).hide();&lt;br&gt;            $(&lt;span style="color: #006080"&gt;'#lblResponse'&lt;/span&gt;).show();&lt;br&gt;        }&lt;br&gt;    });&lt;br&gt;});&lt;br&gt;&lt;br&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; ValidateFields() {&lt;br&gt;    &lt;span style="color: #008000"&gt;// Start validation:&lt;/span&gt;&lt;br&gt;    $.validity.start();&lt;br&gt;&lt;br&gt;    &lt;span style="color: #008000"&gt;// Validate fields&lt;/span&gt;&lt;br&gt;    $(&lt;span style="color: #006080"&gt;"#txtbxName"&lt;/span&gt;).require();&lt;br&gt;    $(&lt;span style="color: #006080"&gt;"#txtbxEmail"&lt;/span&gt;)&lt;br&gt;        .require()&lt;br&gt;        .match(&lt;span style="color: #006080"&gt;"email"&lt;/span&gt;);&lt;br&gt;&lt;br&gt;    &lt;span style="color: #008000"&gt;// Validate password strength &amp;amp; match&lt;/span&gt;&lt;br&gt;    $(&lt;span style="color: #006080"&gt;"input[type='password']"&lt;/span&gt;)&lt;br&gt;        .require()&lt;br&gt;        .match(/^.{8,20}$/, &lt;span style="color: #006080"&gt;"Passwords must be at least 8 characters."&lt;/span&gt;)&lt;br&gt;        .equal(&lt;span style="color: #006080"&gt;"Passwords do not match."&lt;/span&gt;); &lt;br&gt;&lt;br&gt;    &lt;span style="color: #008000"&gt;// All of the validator methods have been called:&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #008000"&gt;// End the validation session:&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;var&lt;/span&gt; result = $.validity.end();&lt;br&gt;&lt;br&gt;    &lt;span style="color: #008000"&gt;// Return whether it's okay to proceed with the Ajax:&lt;/span&gt;&lt;br&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; result.valid;&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;That's It!&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;That's all it takes, very simple and straight forward. Just that tiny bit of Javascript gives you rich input validation and a nice user experience!&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Demo Download&lt;/h3&gt;&lt;br /&gt;&lt;p&gt;Here is a little ASP.NET MVC demo that I threw together using jQuery Validity so you can see it in action and play with it.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedicon.aspx/Public/jQueryValidityDemo.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;- Aaron Schnieder&lt;br&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/Rb-x7XvTkRk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/2817932822542320827/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=2817932822542320827" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/2817932822542320827?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/2817932822542320827?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/Rb-x7XvTkRk/jquery-ajax-validation-using-validity.html" title="jQuery AJAX Validation Using The Validity Plugin" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_QQqEHtDW18M/TAaFPyMUpnI/AAAAAAAAAII/tURha6OxmH8/s72-c/jQueryValidityScreenshot_thumb2.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.schnieds.com/2010/06/jquery-ajax-validation-using-validity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AEQng4eCp7ImA9WxFWFEQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-5795864670213029069</id><published>2010-06-02T09:21:00.001-07:00</published><updated>2010-06-02T09:21:43.630-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T09:21:43.630-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="code snippets" /><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>Windows Live Writer Code Snippet Plugin</title><content type="html">&lt;p&gt;I love &lt;a href="http://windowslivewriter.spaces.live.com/" target="_blank"&gt;Windows Live Writer&lt;/a&gt; as a blogging application and use it pretty much exclusively for writing my blog posts. The only downside is that I have found it difficult to get code snippets formatted correctly in my posts. Luckily a friend of mine, &lt;a href="http://publicityson.blogspot.com/" target="_blank"&gt;Tyson Swing&lt;/a&gt;, turned me on to a great code snippet plugin for Windows Live writer.&lt;/p&gt; &lt;h3&gt;CodeSnippet&lt;/h3&gt; &lt;p&gt;The Windows Live Writer code snippet plugin is aptly named “CodeSnippet” and you can download it here: &lt;a href="http://wlwplugincollection.codeplex.com/" target="_blank"&gt;http://wlwplugincollection.codeplex.com/&lt;/a&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;This Windows Live Writer code snippet plugin is provided by Leo Vidosola. &lt;a href="http://lvildosola.blogspot.com/" target="_blank"&gt;http://lvildosola.blogspot.com/&lt;/a&gt;&lt;/p&gt; &lt;h3&gt;Settings&lt;/h3&gt; &lt;p&gt;Personally, I have found that the following settings work well for the “CodeSnippet” plug in:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Be sure to select the correct code language  &lt;li&gt;No Line Numbers  &lt;li&gt;No Alternate Lines  &lt;li&gt;No Container&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Aaron Schnieder&lt;br&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/E-IG4MGa3Jo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/5795864670213029069/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=5795864670213029069" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/5795864670213029069?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/5795864670213029069?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/E-IG4MGa3Jo/windows-live-writer-code-snippet-plugin.html" title="Windows Live Writer Code Snippet Plugin" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.schnieds.com/2010/06/windows-live-writer-code-snippet-plugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUIBRX89fip7ImA9WxFRGU0.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4127471462764346044</id><published>2010-05-03T09:19:00.000-07:00</published><updated>2010-05-03T09:19:14.166-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-03T09:19:14.166-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>jQuery Ajax Error Handling – How To Show Custom Error Messages</title><content type="html">&lt;h3&gt;Books I recommend on this subject&lt;/h3&gt;&lt;p&gt;The following books are the best references I have found when working with jQuery and ASP.NET MVC. I highly recommend both.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/1933988355?ie=UTF8&amp;amp;tag=aasconasne-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1933988355"&gt;jQuery in Action&lt;/a&gt;&lt;img style="border-bottom-style: none !important; border-right-style: none !important; margin: 0px; border-top-style: none !important; border-left-style: none !important" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=aasconasne-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1933988355" width="1" height="1" /&gt; &lt;/p&gt;&lt;p&gt;&lt;a href="http://www.amazon.com/gp/product/1430210079?ie=UTF8&amp;amp;tag=aasconasne-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1430210079"&gt;Pro ASP.NET MVC Framework&lt;/a&gt;&lt;img style="border-bottom-style: none !important; border-right-style: none !important; margin: 0px; border-top-style: none !important; border-left-style: none !important" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=aasconasne-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1430210079" width="1" height="1" /&gt; &lt;/p&gt;&lt;h3&gt;So you want to make your error feedback nice for your users…&lt;/h3&gt;&lt;p&gt;Kind of an ironic statement isn’t it? We obviously want to avoid errors if at all possible in our applications, but when errors do occur then we want to provide some nice feedback to our users. The worst thing that can happen is to blow up a huge server exception page when something goes wrong or equally bad is not providing any feedback at all and leaving the user in the dark. Although I do not recommend displaying actual .NET Framework exception messages or stack traces to the user in most instances; they are usually not helpful to the user and can be a security concern.&lt;/p&gt;&lt;p&gt;Using the &lt;a href="http://api.jquery.com/category/ajax/"&gt;jQuery Ajax methods&lt;/a&gt; ($.ajax(), $.get(), $.post(), etc.) to call your controller (in ASP.NET MVC) or web service (in ASP.NET) to perform server side actions (GET, POST, etc.) is a great way to provide a great user experience in ASP.NET applications while also interacting with a server to get or update data. However, if an error occurs on the server, or an exception takes place in the server side methods, then the problem can often be hidden from the user. Because a Postback is not taking place, if you do not handle errors on the jQuery Ajax methods and display some feedback then the user will be left in a state where they have no idea that a problem has occurred. Luckily, we can use the error callback on the jQuery Ajax methods along with some controller information to display some nice error feedback to the user.&lt;/p&gt;&lt;h3&gt;Setting up layers to handle and communicate problems&lt;/h3&gt;&lt;p&gt;I have defined an Entities assembly that contains an object to be used to provide operation feedback between assemblies and methods.&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;namespace&lt;/span&gt; jQueryCustomErrorHandling.Entities
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; OperationResult
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; Success { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Message { &lt;span style="color: #0000ff"&gt;get&lt;/span&gt;; &lt;span style="color: #0000ff"&gt;set&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;My persistence and logic methods pass an OperationResult as a return type.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Persistence Layer&lt;/strong&gt;&amp;#160; &lt;br /&gt;
&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IMyDao
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;OperationResult MyDaoMethod(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; fail);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyDao : IMyDao
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; OperationResult MyDaoMethod(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; fail)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;var result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; OperationResult() { Success = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt; };
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;try&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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; (fail)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Exception(&amp;quot;&lt;span style="color: #8b0000"&gt;Persistance Error&lt;/span&gt;&amp;quot;);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;catch&lt;/span&gt; (Exception ex)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;result.Success = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;result.Message = ex.Message;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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; result;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Logic Layer &lt;br /&gt;
&lt;/strong&gt;&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IMyLogic
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;OperationResult MyLogicMethod(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; fail);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyLogic : IMyLogic
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;private&lt;/span&gt; IMyDao _myDao;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; IMyDao MyDao
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _myDao ?? (_myDao = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; MyDao()); }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;set&lt;/span&gt; { _myDao = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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;public&lt;/span&gt; OperationResult MyLogicMethod(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; fail)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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; MyDao.MyDaoMethod(fail);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;h3&gt;And now communicating the errors to the presentation layer&lt;/h3&gt;&lt;p&gt;I have created a controller method that calls the logic layer. Notice that if the OperationResult.Success property is set to false, I throw an exception in the controller method. The catch block handles that exception and sets the Response.StatusCode to an error and then also does a Response.Write of the error message. This is how we communicate with the jQuery error callback that there was an error on the server side.&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;[AcceptVerbs(HttpVerbs.Post)]
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; JsonResult MyPostMethod(&lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; fail)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;try&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Call the logic layer to make the updates&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;OperationResult result = MyLogic.MyLogicMethod(fail);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// If the result is a failure, throw an exception&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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; (!result.Success)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Exception(result.Message);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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; Json(result.Message);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;catch&lt;/span&gt; (Exception ex)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;string&lt;/span&gt; errorMsg = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;Error posting data: {0}&lt;/span&gt;&amp;quot;, ex.Message);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Response.StatusCode = 500;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;Response.Write(errorMsg);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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; Json(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;p&gt;The jQuery.ajax configuration looks like this:&lt;/p&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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; CallAjaxMethod(fail) {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$('#lblMethodError').hide();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$('#lblMethodSuccess').hide();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$.ajax({
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;type: &amp;quot;&lt;span style="color: #8b0000"&gt;POST&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;url: &amp;quot;&lt;span style="color: #8b0000"&gt;/Home/MyPostMethod&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;data: &amp;quot;&lt;span style="color: #8b0000"&gt;fail=&lt;/span&gt;&amp;quot; + fail,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;dataType: &amp;quot;&lt;span style="color: #8b0000"&gt;json&lt;/span&gt;&amp;quot;,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;error: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(xhr, &lt;span style="color: #0000ff"&gt;status&lt;/span&gt;, error) {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Show the error&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$('#lblMethodError').text(xhr.responseText);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$('#lblMethodError').show();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;success: &lt;span style="color: #0000ff"&gt;function&lt;/span&gt;(data, textSuccess) {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// show the success message&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;$('#lblMethodSuccess').show();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;h3&gt;The presentation&lt;/h3&gt;&lt;p&gt;In the view I simply have two hidden labels that I show or hide depending on whether or not the jQuery.ajax call was successful. I populate the error label with the custom error message from the server in the jQuery.ajax error callback if a problem occurred on the server side.&lt;/p&gt;&lt;p&gt;This provides a nice way to give feedback to the user when problems occur on the server side and also establishes a nice error handling pattern within your projects.&lt;/p&gt;&lt;h3&gt;Demo download&lt;/h3&gt;&lt;p&gt;I put together a working demo with full source code that you can download below.&lt;/p&gt;&lt;p&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedicon.aspx/Public/jQueryCustomErrorHandling.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;- Aaron Schnieder &lt;br /&gt;
&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/8QvG9KA3j4o" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4127471462764346044/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4127471462764346044" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4127471462764346044?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4127471462764346044?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/8QvG9KA3j4o/jquery-ajax-error-handling-how-to-show.html" title="jQuery Ajax Error Handling – How To Show Custom Error Messages" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.schnieds.com/2010/05/jquery-ajax-error-handling-how-to-show.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEGQn87eyp7ImA9WxFSGUU.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4121788602809691108</id><published>2010-04-22T16:57:00.001-07:00</published><updated>2010-04-22T16:57:03.103-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-22T16:57:03.103-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>Best jQuery Libraries, Plug-Ins and Controls</title><content type="html">&lt;h3&gt;Worried About The Loss Of ASP.NET Controls in MVC? Don’t Be&lt;/h3&gt;  &lt;p&gt;If you are hesitant of moving to ASP.NET MVC because you are worried about losing all of the awesome ASP.NET controls that you are so used to using, don’t be. Wonderful client side controls already exist to replace most, if not all, of the most used ASP.NET controls (and these controls provide a MUCH BETTER user experience.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;First off, if you are looking for an excellent jQuery book I HIGHLY recommend&lt;/strong&gt; &lt;a href="http://www.amazon.com/gp/product/1933988355?ie=UTF8&amp;amp;tag=aasconasne-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1933988355"&gt;jQuery in Action&lt;/a&gt;&lt;img style="border-bottom-style: none !important; border-right-style: none !important; margin: 0px; border-top-style: none !important; border-left-style: none !important" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=aasconasne-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1933988355" width="1" height="1" /&gt; &lt;/p&gt;  &lt;p&gt;Here are the best jQuery libraries, plug-ins and controls that I have found to date. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;What is a CDN (Content Delivery Network)?      &lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Content_delivery_network"&gt;http://en.wikipedia.org/wiki/Content_delivery_network&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;  &lt;h3&gt;jQuery&lt;/h3&gt;  &lt;p&gt;The best client site Javascript library to date. Client side development without jQuery just doesn’t make sense.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://jquery.com/"&gt;http://jquery.com/&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Google CDN&lt;/strong&gt; &lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery"&gt;http://code.google.com/apis/ajaxlibs/documentation/index.html#jquery&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Microsoft CDN&lt;/strong&gt; &lt;a href="http://www.asp.net/ajaxlibrary/cdn.ashx"&gt;http://www.asp.net/ajaxlibrary/cdn.ashx&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;jQueryUI&lt;/h3&gt;  &lt;p&gt;Excellent user interface controls, interactions and effects that are built on top of the jQuery framework. Provides themes for customized look and feel and out of the box excellent user experience.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Calendar control &lt;/li&gt;    &lt;li&gt;Dialog / Modal control &lt;/li&gt;    &lt;li&gt;Tab control &lt;/li&gt;    &lt;li&gt;Accordion control &lt;/li&gt;    &lt;li&gt;Animation effects &lt;/li&gt;    &lt;li&gt;Draggable / Droppable interaction &lt;/li&gt;    &lt;li&gt;Much, much, much more…. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://jqueryui.com/"&gt;http://jqueryui.com/&lt;/a&gt;     &lt;br /&gt;&lt;strong&gt;Google CDN&lt;/strong&gt; &lt;a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#jqueryUI"&gt;http://code.google.com/apis/ajaxlibs/documentation/index.html#jqueryUI&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Date.js&lt;/h3&gt;  &lt;p&gt;Sweet library that makes working with dates on the client side infinitely easier. Great for date calculations, date ranges and date validation.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Text date references; ‘last week’ will return the date for 7 days ago &lt;/li&gt;    &lt;li&gt;‘yesterday’ returns yesterday’s date &lt;/li&gt;    &lt;li&gt;Date.parse('1 month ago').moveToFirstDayOfMonth() returns the first day of last month &lt;/li&gt;    &lt;li&gt;Much, much more… &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://www.datejs.com/"&gt;http://www.datejs.com/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;Validity Validation Plug In&lt;/h3&gt;  &lt;p&gt;The jQuery Validity plug-in is an extremely flexible, lightweight and easy to use validation library. You can validate anything on the fly in any instance. It doesn’t require a form or anything else, just setup the validation rules (there are a bunch of common validations built in) and go.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://validity.thatscaptaintoyou.com/"&gt;http://validity.thatscaptaintoyou.com/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;DateRangePicker&lt;/h3&gt;  &lt;p&gt;The DateRangePicker plug-in from the Filament Group is an awesome little user experience element that makes selecting dates so much nicer. You can select predefined dates or date ranges easily (such as last week, last month, yesterday, etc.) and is the best user experience have seen selecting a date range.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://www.filamentgroup.com/lab/date_range_picker_using_jquery_ui_16_and_jquery_ui_css_framework/"&gt;http://www.filamentgroup.com/lab/date_range_picker_using_jquery_ui_16_and_jquery_ui_css_framework/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;jQuery Tools&lt;/h3&gt;  &lt;p&gt;jQuery Tools is an excellent library of user interface elements. It is fairly lightweight and can add some very nice user experience elements to your applications.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Tooltips &lt;/li&gt;    &lt;li&gt;Overlays &lt;/li&gt;    &lt;li&gt;Scrollable Galleries &lt;/li&gt;    &lt;li&gt;Flash Embedding &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://flowplayer.org/tools/index.html"&gt;http://flowplayer.org/tools/index.html&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;jqGrid&lt;/h3&gt;  &lt;p&gt;Ah jqGrid, how I love thee jqGrid. This little beauty is a wonderful Gridview alternative in ASP.NET MVC. I wrote up an overview of using it here: &lt;a href="http://www.schnieds.com/2010/01/gridview-in-aspnet-mvc.html"&gt;http://www.schnieds.com/2010/01/gridview-in-aspnet-mvc.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://www.trirand.com/blog/"&gt;http://www.trirand.com/blog/&lt;/a&gt;&lt;/p&gt;  &lt;h3&gt;jQuery Templates&lt;/h3&gt;  &lt;p&gt;jQuery Templates are a way to accomplish DataBinding in ASP.NET MVC. Basically you pre-define some HTML elements and then when the page is rendering you use a jQuery AJAX call to get some data from the server, create instances of the HTML elements, populate the values and then append the items into the DOM. jQuery Templates makes this process very easy. Here is a nice tutorial on using this plug-in: &lt;a href="http://publicityson.blogspot.com/2009/11/dynamic-content-using-html-templates.html"&gt;http://publicityson.blogspot.com/2009/11/dynamic-content-using-html-templates.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Information, Documentation &amp;amp; Download&lt;/strong&gt; &lt;a href="http://plugins.jquery.com/project/jquerytemplate"&gt;http://plugins.jquery.com/project/jquerytemplate&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/7djRDo5yrh4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4121788602809691108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4121788602809691108" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4121788602809691108?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4121788602809691108?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/7djRDo5yrh4/best-jquery-libraries-plug-ins-and.html" title="Best jQuery Libraries, Plug-Ins and Controls" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.schnieds.com/2010/04/best-jquery-libraries-plug-ins-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0cFSH06eip7ImA9WxBXFEs.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-340156138720655673</id><published>2010-01-25T14:51:00.001-08:00</published><updated>2010-01-25T15:10:19.312-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-25T15:10:19.312-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IIS" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><title>Using Ionics Isapi Rewrite for ASP.NET MVC in IIS 6</title><content type="html">&lt;p&gt;If you are running IIS6 and want to deploy an ASP.NET MVC app it is a royal pain in the behind. Pretty URLs (www.mysite.com/prices instead of www.mysite.com/prices.aspx) aren’t supported out of the box. There are several solutions to this problem. First, you can still use MVC with IIS6 out of the box and just append .mvc to all of your files. This approach works, but you lose the nice URLs. Second, you can add a wildcard mapping that processes EVERY resource in a website through the ASP.NET ISAPI dll (images, css files, javascript, everything!) There is a known performance hit with this method and I found it to be quite noticeable when I tried it. Third, you can configure a URL re-writing module that will enable pretty URLs and do so in a well performing manner.&lt;/p&gt;  &lt;p&gt;I wanted to go with option 3, which is a bit more work but I feel the best overall solution. Unfortunately, most of the information and “How To” posts I found out on the internet didn’t work, were horribly outdated or just didn’t make sense. So with that in mind I download the latest version of Ionic’s open source Isapi Rewrite module, read through their documentation and then worked out a configuration in IIS 6 that got everything working. Here is a step by step process that you can follow to easily (and freely) get ASP.NET MVC pretty URLs running under IIS 6 using Ionic’s Isapi Rewrite module.&lt;/p&gt;  &lt;h3&gt;Ionics Isapi Rewrite Installation and Configuration&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;Download Ionic Isapi Rewrite &lt;a href="http://iirf.codeplex.com/"&gt;http://iirf.codeplex.com/&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;Unzip the contents &lt;/li&gt;    &lt;li&gt;Create the following folder c:\inetpub\IonicRewriter (or a location of your choice) &lt;/li&gt;    &lt;li&gt;Copy IonicIsapiRewriter-2.0-Release-bin\bin\IIRF.dll (from the contents of the download you unzipped) to c:\inetpub\IonicRewrite &lt;/li&gt;    &lt;li&gt;Create a new text document, name it IirfGlobal.ini &lt;/li&gt;    &lt;li&gt;Select both files, right click and choose Properties &lt;/li&gt;    &lt;li&gt;Select the Security tab &lt;/li&gt;    &lt;li&gt;Ensure IIS_WPG has read &amp;amp; execute permissions on both IIRF.dll and IirfGlobal.ini &lt;/li&gt;    &lt;li&gt;Edit IirfGlobal.ini and include the following:      &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 800px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre face="consolas,'Courier New',courier,monospace" size="12px" color="#fbfbfb" style="background- margin: 0em; width: 100%;  "&gt;# IsapiRewrite4.ini&lt;br /&gt;&lt;/pre&gt;&lt;pre face="consolas,'Courier New',courier,monospace" size="12px" color="#fbfbfb" style="background- margin: 0em; width: 100%;  "&gt;## Turn off logging, enable if you need to debug routing&lt;br /&gt;&lt;/pre&gt;&lt;pre face="consolas,'Courier New',courier,monospace" size="12px" color="#fbfbfb" style="background- margin: 0em; width: 100%;  "&gt;#RewriteLog  c:\_Logs\iirfLog.out&lt;br /&gt;&lt;/pre&gt;&lt;pre face="consolas,'Courier New',courier,monospace" size="12px" color="#fbfbfb" style="background- margin: 0em; width: 100%;  "&gt;#RewriteLogLevel 3&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteFilterPriority HIGH&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;IterationLimit 1&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteEngine ON&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;StatusUrl /iirfStatus&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteRule ^/Default\.aspx /Home.mvc [I,L]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteRule ^/$ /Home.mvc [I,L]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteRule ^/([\w]+)$ /$1.mvc [I,L]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;RewriteRule ^/(?!Content|Scripts|App_Data|Images)([\w]*)/(.*) /$1.mvc/$2 [I,L]&lt;/pre&gt;&lt;/pre&gt;   &lt;br /&gt;&lt;strong&gt;&lt;em&gt;** The last rule filters out any files in the Content, Scripts, App_Data and Images folder from the URL rewrite. This prevents a .MVC extension from being appended to root folder of the resource being requested (i.e. mysite.com/Content.mvc/site.css) To add another other folders you want to exclude, just add another |FolderName to the regular expression.&lt;/em&gt;&lt;/strong&gt; &lt;/li&gt;&lt;br /&gt;&lt;br /&gt; &lt;li&gt;Copy the IirfGlobal.ini file to your website directory and rename it to IIRF.ini&lt;/li&gt;  &lt;li&gt;Select IIRF.ini, right click and choose Properties&lt;/li&gt;  &lt;li&gt;Ensure IIS_WPG has read &amp;amp; execute permissions on IIRF.ini&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Internet Information Services (IIS) 6 Configuration&lt;/h3&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;** These configuration instructions are for a single website. If you want to configure the Ionics Isapi Rewrite module for all of IIS 6, perform these steps on the Websites root directory.&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;ol&gt;  &lt;li&gt;Open IIS Manager&lt;/li&gt;  &lt;li&gt;Expand the Web Sites node&lt;/li&gt;  &lt;li&gt;Right click on the web site you want to configure and select Properties&lt;/li&gt;  &lt;li&gt;Select the ISAPI Filters tab&lt;/li&gt;  &lt;li&gt;Click the Add button&lt;/li&gt;  &lt;li&gt;Enter "Ionic Rewriter" for the filter name&lt;/li&gt;  &lt;li&gt;Browse to c:\inetpub\IonicRewriter\IIRF.ddl and select the file (or the location that you placed IIRF.dll into in Step 3)&lt;/li&gt;  &lt;li&gt;Click OK&lt;/li&gt;  &lt;li&gt;Select the Home Directory tab&lt;/li&gt;  &lt;li&gt;Click Configuration&lt;/li&gt;  &lt;li&gt;Click the Add... button under "Application extentions"&lt;/li&gt;  &lt;li&gt;Click the Browse button and select C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll for the executable&lt;/li&gt;  &lt;li&gt;Enter .mvc for the extension&lt;/li&gt;  &lt;li&gt;Limit verbs to: GET,HEAD,POST,DEBUG&lt;/li&gt;  &lt;li&gt;UNCHECK "Verify that file exists"&lt;/li&gt;  &lt;li&gt;Click OK&lt;/li&gt;  &lt;li&gt;Click OK, OK to close the main properties dialog&lt;/li&gt;  &lt;li&gt;In IIS Manager, go to Application Pools and Start/Stop the application pool that your MVC application is running under&lt;/li&gt;  &lt;li&gt;In IIS Manager –&amp;gt; Web Sites, select your MVC web site and stop/start the web site&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;IIRF Status and Troubleshooting&lt;/h3&gt;&lt;ol&gt;  &lt;li&gt;On the server, open Internet Explorer and browse to: &lt;a href="http://yourmvcwebsiteurl/iirfStatus"&gt;http://yourmvcwebsiteurl/iirfStatus&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;You should see the IIRF Status Report if you followed the steps properly&lt;/li&gt;  &lt;li&gt;Specifically check the INI file status for both the Global and Site Specific sections, if there are any problems double check your file locations and file permissions as stated above&lt;/li&gt;  &lt;li&gt;If IIRF still isn’t working correctly, consult the IIRF v2.0 Operator’s Guide located in the contents of the zip file you downloaded under AdminGuide/Help. There is a section in the chm titled “Verifying and Troubleshooting Installation”&lt;/li&gt;  &lt;li&gt;You can also enable logging in the ini files for IIRF and take a look at the IIRF log output to diagnose problems and errors. If there isn’t a log being generated and un-commenting the logging options that means that IIRF isn’t routing properly.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;ASP.NET MVC Application Configuration&lt;/h3&gt;&lt;ol&gt;  &lt;li&gt;Modify your Global.asax route code to handle .mvc routes as follows&lt;br /&gt;   &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 800px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;routes.MapRoute(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    "&lt;span style="color:#8b0000;"&gt;Default.mvc&lt;/span&gt;",                                          &lt;span style="color:#008000;"&gt;// IIS 6 Ionic Isapi Rewrite support&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    "&lt;span style="color:#8b0000;"&gt;{controller}.mvc/{action}/{id}&lt;/span&gt;",                       &lt;span style="color:#008000;"&gt;// URL with parameters&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; { controller = "&lt;span style="color:#8b0000;"&gt;Home&lt;/span&gt;", action = "&lt;span style="color:#8b0000;"&gt;Index&lt;/span&gt;", id = "&lt;span style="color:#8b0000;"&gt;&lt;/span&gt;" }, &lt;span style="color:#008000;"&gt;// Parameter defaults&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;    &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; { controller = @"&lt;span style="color:#8b0000;"&gt;[^\.]*&lt;/span&gt;" }                          &lt;span style="color:#008000;"&gt;// Don't look for a controller for non mvc files (ico, images, etc.)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"&gt;);&lt;/pre&gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt; &lt;li&gt;Build &amp;amp; publisher your MVC application&lt;/li&gt;  &lt;li&gt;Copy your MVC application to your server, restart the application pool once more and your nice routes should now work&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;Download&lt;/h3&gt;&lt;p&gt;Here is a zip file containing the IIRF.dll, IirfGlobal.ini and IIRF.ini files as well as a sample ASP.NET MVC application with the Global.asax routing setup. It is everything you need and you can just copy/paste these files into your web application using the instructions above.&lt;/p&gt;&lt;br /&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedicon.aspx/Public/ASP^_NET%20MVC%20Iconics%20Rewriter%20Example.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Aaron Schnieder&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/9FqQD9mphS8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/340156138720655673/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=340156138720655673" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/340156138720655673?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/340156138720655673?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/9FqQD9mphS8/using-ionics-isapi-rewrite-for-aspnet.html" title="Using Ionics Isapi Rewrite for ASP.NET MVC in IIS 6" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.schnieds.com/2010/01/using-ionics-isapi-rewrite-for-aspnet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QMSXo_fyp7ImA9WxFSGUo.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-2382750594729283460</id><published>2010-01-21T14:12:00.001-08:00</published><updated>2010-04-22T16:36:28.447-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-22T16:36:28.447-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="code snippets" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>GridView in ASP.NET MVC</title><content type="html">&lt;p&gt;One of the controls that it seems like everyone in the ASP.NET community is most concerned about losing when switching to ASP.NET MVC is the ubiquitous GridView control to render grid based data. Fear not ASP.NET community there is a GREAT alternative that, in my opinion, has a lot more to offer than the GridView in terms of user experience.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;First off, if you are looking for an excellent jQuery book I HIGHLY recommend &lt;a href="http://www.amazon.com/gp/product/1933988355?ie=UTF8&amp;amp;tag=aasconasne-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1933988355"&gt;jQuery in Action&lt;/a&gt;&lt;img style="border-bottom-style: none !important; border-right-style: none !important; margin: 0px; border-top-style: none !important; border-left-style: none !important" border="0" alt="" src="http://www.assoc-amazon.com/e/ir?t=aasconasne-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1933988355" width="1" height="1" /&gt; &lt;/p&gt;&lt;p&gt;I have seen a few different solutions to display grid data in ASP.NET MVC. There is of course a for loop in the View that will render a table (or CSS based layout that mimics a table.) Telerik is putting together a commercially available GridView for MVC, which looks pretty nice but also has a licensing cost associated with it (if you are using it in a commercial application). &lt;a href="http://demos.telerik.com/aspnet-mvc"&gt;http://demos.telerik.com/aspnet-mvc&lt;/a&gt; Both solutions work, but I don't like the downsides of either, which is where jqGrid comes in. jqGrid is an awesome, free, open source jQuery based grid control.&lt;br /&gt;
&lt;/p&gt;&lt;h3&gt;jqGrid&lt;/h3&gt;&lt;p&gt;Application site: &lt;a href="http://www.trirand.com/blog/"&gt;http://www.trirand.com/blog/&lt;/a&gt;&lt;br /&gt;
Demos: &lt;a href="http://trirand.com/blog/jqgrid/jqgrid.html"&gt;http://trirand.com/blog/jqgrid/jqgrid.html&lt;/a&gt;&lt;br /&gt;
jqGrid is a very fully featured grid that supports loading data client side via AJAX (JSON) calls, paging, sorting, row editing, etc., etc. etc. I believe it can do everything the Telerik control can do and comes with a fully free license for any application.&lt;br /&gt;
&lt;/p&gt;&lt;h3&gt;ASP.NET MVC jqGrid Demo Application&lt;/h3&gt;&lt;p&gt;Since I have already used jqGrid in several applications and got everything working pretty smoothly I figured that it would be helpful to make a full demo application available to the community so it can be downloaded and then the pattern easily adapted into ASP.NET MVC applications.&lt;br /&gt;
&lt;a href="http://lh3.ggpht.com/_QQqEHtDW18M/S1jRTkRoBOI/AAAAAAAAAHE/FTx61Zw0GiE/s1600-h/image3.png"&gt;&lt;img alt="image" border="0" height="298" src="http://lh6.ggpht.com/_QQqEHtDW18M/S1jRT5cug-I/AAAAAAAAAHI/mm8qyw9DYO0/image_thumb1.png?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline;" title="image" width="644" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/p&gt;&lt;h3&gt;JSON data source&lt;/h3&gt;&lt;p&gt;I setup the grid to use a controller method that will return a JSON result formatted so that the jqGrid can use it. In the example the call to get the JSON data can be manipulated on the fly and the contents of the grid changed via an AJAX call by filtering the sales data by Date Range.&lt;br /&gt;
&lt;/p&gt;&lt;pre style="background-color: #fbfbfb; border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; border-right: #cecece 1px solid; border-top: #cecece 1px solid; min-height: 40px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 800px;"&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;public&lt;/span&gt; ActionResult JsonSalesCollection(DateTime startDate, DateTime endDate,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; sidx, &lt;span style="color: blue;"&gt;string&lt;/span&gt; sord, &lt;span style="color: blue;"&gt;int&lt;/span&gt; page, &lt;span style="color: blue;"&gt;int&lt;/span&gt; rows)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;SalesLogic logicLayer = &lt;span style="color: blue;"&gt;new&lt;/span&gt; SalesLogic();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;List&amp;lt;Sale&amp;gt; context;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: green;"&gt;// If we aren't filtering by date, return this month's contributions&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;if&lt;/span&gt; (startDate == DateTime.MinValue || endDate == DateTime.MinValue)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;context = logicLayer.GetSales();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;else&lt;/span&gt; &lt;span style="color: green;"&gt;// Filter by specified date range&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;context = logicLayer.GetSalesByDateRange(startDate, endDate);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: green;"&gt;// Calculate page index, total pages, etc. for jqGrid to us for paging&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; pageIndex = Convert.ToInt32(page) - 1;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; pageSize = rows;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; totalRecords = context.Count();
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;int&lt;/span&gt; totalPages = (&lt;span style="color: blue;"&gt;int&lt;/span&gt;)Math.Ceiling((&lt;span style="color: blue;"&gt;float&lt;/span&gt;)totalRecords / (&lt;span style="color: blue;"&gt;float&lt;/span&gt;)pageSize);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: green;"&gt;// Order the results based on the order passed into the method&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;string&lt;/span&gt; orderBy = &lt;span style="color: blue;"&gt;string&lt;/span&gt;.Format("&lt;span style="color: darkred;"&gt;{0} {1}&lt;/span&gt;", sidx, sord);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;var sales = context.AsQueryable()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;.OrderBy(orderBy) &lt;span style="color: green;"&gt;// Uses System.Linq.Dynamic library for sorting&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;.Skip(pageIndex * pageSize)
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;.Take(pageSize);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: green;"&gt;// Format the data for the jqGrid&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;var jsonData = &lt;span style="color: blue;"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;total = totalPages,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;page = page,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;records = totalRecords,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;rows = (
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;from s &lt;span style="color: blue;"&gt;in&lt;/span&gt; sales
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;select &lt;span style="color: blue;"&gt;new&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;i = s.Id,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;cell = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: blue;"&gt;string&lt;/span&gt;[] {
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Id.ToString(),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Quantity.ToString(),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Product,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Customer,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Date.ToShortDateString(), 
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;s.Amount.ToString("&lt;span style="color: darkred;"&gt;c&lt;/span&gt;")
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;}
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;}).ToArray()
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;};
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: green;"&gt;// Return the result in json&lt;/span&gt;
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;&lt;span style="color: blue;"&gt;return&lt;/span&gt; Json(jsonData);
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Javascript setup&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
The call to configure the jqGrid when the document ready event is fired is pretty straight forward.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #fbfbfb; border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; border-right: #cecece 1px solid; border-top: #cecece 1px solid; min-height: 40px; overflow: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; width: 800px;"&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;jQuery("&lt;span style="color: darkred;"&gt;#list&lt;/span&gt;").jqGrid({
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;url: gridDataUrl + '?startDate=' + startDate.toJSONString() + '&amp;amp;endDate=' + endDate.toJSONString(),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;datatype: "&lt;span style="color: darkred;"&gt;json&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;mtype: 'GET',
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;colNames: ['Sale Id', 'Quantity', 'Product', 'Customer', '&lt;span style="color: blue;"&gt;Date&lt;/span&gt;', 'Amount'],
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;colModel: [
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: 'Id', index: 'Id', width: 50, align: 'left' },
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: 'Quantity', index: 'Quantity', width: 100, align: 'left' },
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: 'Product', index: 'Product', width: 100, align: 'left' },
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: 'Customer', index: 'Customer', width: 100, align: 'left' },
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: '&lt;span style="color: blue;"&gt;Date&lt;/span&gt;', index: '&lt;span style="color: blue;"&gt;Date&lt;/span&gt;', width: 100, align: 'left' },
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;{ &lt;span style="color: blue;"&gt;name&lt;/span&gt;: 'Amount', index: 'Amount', width: 100, align: 'right'}],
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;rowNum: 20,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;rowList: [10, 20, 30],
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;imgpath: gridimgpath,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;height: 'auto',
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;width: '700',
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;pager: jQuery('#pager'),
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;sortname: 'Id',
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;viewrecords: &lt;span style="color: blue;"&gt;true&lt;/span&gt;,
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;sortorder: "&lt;span style="color: darkred;"&gt;desc&lt;/span&gt;",
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;caption: "&lt;span style="color: darkred;"&gt;Sales&lt;/span&gt;"
&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; font-family: consolas,'Courier New',courier,monospace; font-size: 12px; margin: 0em; width: 100%;"&gt;});&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Download&lt;/h3&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the full application for you to download and play with. &lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://cid-a62623415e09df8d.skydrive.live.com/embedicon.aspx/Public/MvcDemojqGrid.zip" style="background-color: #fcfcfc; height: 115px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; width: 98px;" title="Preview"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
I hope this is helpful in your MVC applications.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Aaron&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/QJVi5b4-wro" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/2382750594729283460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=2382750594729283460" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/2382750594729283460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/2382750594729283460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/QJVi5b4-wro/gridview-in-aspnet-mvc.html" title="GridView in ASP.NET MVC" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_QQqEHtDW18M/S1jRT5cug-I/AAAAAAAAAHI/mm8qyw9DYO0/s72-c/image_thumb1.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.schnieds.com/2010/01/gridview-in-aspnet-mvc.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcMRHwyfSp7ImA9WxBRFUo.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4798635570689837106</id><published>2010-01-03T17:54:00.001-08:00</published><updated>2010-01-03T17:54:45.295-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-03T17:54:45.295-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="unit testing" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net mvc" /><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><category scheme="http://www.blogger.com/atom/ns#" term="jQuery" /><title>ASP.NET MVC Locale User Control (State/Province, Country)</title><content type="html">&lt;p&gt;A while back I wrote a locale control for ASP.NET that gave you a nice and easy way to plug in a cascading state/province – country control into your ASP.NET websites. Now that I have moved on to using ASP.NET MVC for my new projects I needed the same control, only this time in MVC. There were aspects of the previous version of the control that I didn’t like and wanted to refactor anyways, specifically the usage of an UpdatePanel (YUCK), reliance on PostBacks, no unit tests and poor separation of concerns for the presentation, logic and persistence layers. I now present to you the brand new ASP.NET MVC version of my Locale control with all of those issues addressed.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/_QQqEHtDW18M/S0FKY80Qq7I/AAAAAAAAAG8/wbahAvjuJwM/s1600-h/LocaleControlScreenShot4.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="LocaleControlScreenShot" border="0" alt="LocaleControlScreenShot" src="http://lh6.ggpht.com/_QQqEHtDW18M/S0FKY3IFrgI/AAAAAAAAAHA/C-NTfVwcbRQ/LocaleControlScreenShot_thumb2.png?imgmax=800" width="660" height="184" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Overview of the ASP.NET MVC Locale User Control&lt;/h3&gt;  &lt;ul&gt;   &lt;li&gt;ASP.NET MVC v1 User Control (Partial View) &lt;/li&gt;    &lt;li&gt;jQuery handles the change events and retrieves new State/Province lists via a JSON call &lt;/li&gt;    &lt;li&gt;Separation of concerns between the Presentation Layer, Logic Layer and Persistence Layer &lt;/li&gt;    &lt;li&gt;Easily customizable data source via the LocaleDao persistence class &lt;/li&gt;    &lt;li&gt;Unit tests with full dependency injection for all Controller and Logic methods &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Basic Locale User Control Usage&lt;/h3&gt;  &lt;p&gt;Add the &lt;strong&gt;user control to your view&lt;/strong&gt;:     &lt;br /&gt;&lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 800px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="background-color: #ffff00; color: black"&gt;&amp;lt;%&lt;/span&gt; Html.RenderPartial(&amp;quot;LocaleUserControl&amp;quot;); &lt;span style="background-color: #ffff00; color: black"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode-wrapper"&gt;&lt;strong&gt;Locale User Control View&lt;/strong&gt;: &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 800px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="background-color: #ffff00; color: black"&gt;&amp;lt;%@ Control Language=&amp;quot;C#&amp;quot; Inherits=&amp;quot;System.Web.Mvc.ViewUserControl&amp;quot; %&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;for&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;StatesProvinces&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;State / Province: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="background-color: #ffff00; color: black"&gt;&amp;lt;%&lt;/span&gt;= Html.DropDownList(&amp;quot;StatesProvinces&amp;quot;) &lt;span style="background-color: #ffff00; color: black"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt; &lt;span style="color: #ff0000"&gt;for&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Countries&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Country: &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;label&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="background-color: #ffff00; color: black"&gt;&amp;lt;%&lt;/span&gt;= Html.DropDownList(&amp;quot;Countries&amp;quot;) &lt;span style="background-color: #ffff00; color: black"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt; &lt;span style="color: #ff0000"&gt;type&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    $(function() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        var countries = $(&amp;quot;#Countries&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        var statesprovinces = $(&amp;quot;#StatesProvinces&amp;quot;);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        countries.change(function() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            statesprovinces.find('option').remove();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            $.getJSON('/Base/StatesProvinces', { countryId: countries.val() }, function(data) {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                $(data).each(function() {&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    $(&amp;quot;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt; &lt;span style="color: #ff0000"&gt;value&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot; + this.Id + &amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&amp;quot; + this.Name + &amp;quot;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;option&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&amp;quot;).appendTo(statesprovinces);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;script&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode-wrapper"&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="csharpcode-wrapper"&gt;The &lt;strong&gt;BaseController&lt;/strong&gt; class holds the generic methods to support this user control (and other generic shared user controls in your project.) &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 800px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BaseController : Controller&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #008000"&gt;// Dependency&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;protected&lt;/span&gt; ILogicFactory _logicFactory;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; ILogicFactory LogicFactory&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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;get&lt;/span&gt; { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _logicFactory ?? &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; LogicFactory(); }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;set&lt;/span&gt; { _logicFactory = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// Gets the states provinces select list.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;country&amp;quot;&amp;gt;The country to filter the states/provinces list by.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;selectedStateProvince&amp;quot;&amp;gt;The State/Province to select. Pass null if no default State/Province selected.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; SelectList GetStatesProvincesSelectList(Country country, StateProvince selectedStateProvince)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Create the object to return&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            SelectList slSps = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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; (country != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;// Get the collection of states and provinces&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                List&amp;lt;StateProvince&amp;gt; statesProvinces = LogicFactory.LocaleLogic.GetStateProvincesByCountry(country.Id);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;// Build a selectlist from the statesprovinces collection&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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; (statesProvinces != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    slSps = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SelectList(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    statesProvinces.Select(s =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SelectListItem&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                        Text = s.Name,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                        Value = s.Id.ToString()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    , &amp;quot;&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Text&lt;/span&gt;&amp;quot;, selectedStateProvince == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty : selectedStateProvince.Id.ToString());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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; slSps;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// Gets the countries select list.&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;param name=&amp;quot;selectedCountry&amp;quot;&amp;gt;The country to select. Pass null if no default country selected.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        &lt;span style="color: #808080"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; SelectList GetCountriesSelectList(Country selectedCountry)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Get the collection of countries, select United States by default&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            List&amp;lt;Country&amp;gt; countries = LogicFactory.LocaleLogic.GetCountries();&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Create the object to return&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            SelectList slCountries = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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; (countries != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                &lt;span style="color: #008000"&gt;// Build a selectlist from the countries collection&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                slCountries = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SelectList(&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                countries.Select(c =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SelectListItem&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    Text = c.Name,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                    Value = c.Id.ToString()&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                , &amp;quot;&lt;span style="color: #8b0000"&gt;Value&lt;/span&gt;&amp;quot;, &amp;quot;&lt;span style="color: #8b0000"&gt;Text&lt;/span&gt;&amp;quot;, selectedCountry == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty : selectedCountry.Id.ToString());&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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; slCountries;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        [AcceptVerbs(HttpVerbs.Get)]&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;public&lt;/span&gt; ActionResult StatesProvinces(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; countryId)&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Returns JSON collection of stateprovince that are associated&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// with the countryId passed in&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            List&amp;lt;StateProvince&amp;gt; sps = LogicFactory.LocaleLogic.GetStateProvincesByCountry(countryId);&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;            &lt;span style="color: #008000"&gt;// Format the JSON return&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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; Json(sps.Select(s =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                s.Id,&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;                s.Name&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; 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: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    }&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Data Source&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The data source for the locale control is an XML file that is included in the App_Data folder. You might want to put this data into your database and then use a nice ORM like NHibernate to load the data up in the persistence layer rather than relying on the XML file. This is very easy to accomplish by changing the LocaleDao class, everything else should just work after you swap out the back end.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Unit Tests&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;I used Microsoft Visual Studio Tests to write unit tests for all of the controller methods and logic layer methods that had any sort of logic in them. I also used &lt;a href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; to mock the dependencies in the methods under test and ensure the viability of the tests. You should be able move these unit tests into your project when you use the Locale user control. If you aren’t using the Visual Studio Test framework and are using NUnit instead, it is quite easy to change the syntax.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Download&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;You can download the full solution including the example MVC application, locale user control and unit tests below.&lt;/p&gt;&lt;br /&gt;&lt;iframe style="padding-bottom: 0px; background-color: #fcfcfc; padding-left: 0px; width: 98px; padding-right: 0px; height: 115px; padding-top: 0px" title="Preview" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedicon.aspx/Public/MvcLocaleControl.zip" frameborder="0" marginwidth="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;- Aaron &lt;br /&gt;  &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/RvpnG1N_OBI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4798635570689837106/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4798635570689837106" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4798635570689837106?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4798635570689837106?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/RvpnG1N_OBI/aspnet-mvc-locale-user-control.html" title="ASP.NET MVC Locale User Control (State/Province, Country)" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_QQqEHtDW18M/S0FKY3IFrgI/AAAAAAAAAHA/C-NTfVwcbRQ/s72-c/LocaleControlScreenShot_thumb2.png?imgmax=800" height="72" width="72" /><thr:total>4</thr:total><feedburner:origLink>http://www.schnieds.com/2010/01/aspnet-mvc-locale-user-control.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUFRH0yeCp7ImA9WxBXFE0.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-8154708446522135198</id><published>2010-01-03T12:05:00.001-08:00</published><updated>2010-01-24T22:16:55.390-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-24T22:16:55.390-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="technology" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>Essential Free Software For .NET Developers</title><content type="html">&lt;p&gt;Every software nerd has their suite of essential free applications they can’t live without, here’s mine:&lt;/p&gt;  &lt;h2&gt;Development Freebies&lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;Visual Studio Express Editions&lt;/strong&gt; &lt;a href="http://www.microsoft.com/exPress/"&gt;http://www.microsoft.com/exPress/&lt;/a&gt;     &lt;br /&gt;Free versions of the most excellent IDE, Visual Studio 2008.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;jQuery &lt;/strong&gt;&lt;a href="http://jquery.com/"&gt;http://jquery.com/&lt;/a&gt;     &lt;br /&gt;Most awesomest javascript library ever; if I could marry it I would.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;GhostDoc&lt;/strong&gt; &lt;a href="http://submain.com/products/ghostdoc.aspx"&gt;http://submain.com/products/ghostdoc.aspx&lt;/a&gt;     &lt;br /&gt;Makes XML method documentation in .NET very smooth.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;NUnit&lt;/strong&gt; &lt;a href="http://www.nunit.org/index.php"&gt;http://www.nunit.org/index.php&lt;/a&gt;     &lt;br /&gt;Fast and lightweight unit testing library for .NET.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Firebug&lt;/strong&gt; &lt;a href="http://getfirebug.com/"&gt;http://getfirebug.com/&lt;/a&gt;     &lt;br /&gt;_MOST USEFUL WEB DEVELOPMENT TOOL EVER CREATED_ Nuff said.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Moq&lt;/strong&gt; &lt;a href="http://code.google.com/p/moq/"&gt;http://code.google.com/p/moq/&lt;/a&gt;     &lt;br /&gt;Excellent mocking framework for dependency injection in unit tests.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;NHibernate&lt;/strong&gt; &lt;a href="https://www.hibernate.org/343.html"&gt;https://www.hibernate.org/343.html&lt;/a&gt;     &lt;br /&gt;Absolutely incredible ORM package, this is what entity framework should be. If you are using DataSets, entity framework, LINQ to Sql, etc. stop right now and go with Domain Driven Design and NHibernate.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Expresso&lt;/strong&gt; &lt;a href="http://www.ultrapico.com/Expresso.htm"&gt;http://www.ultrapico.com/Expresso.htm&lt;/a&gt;     &lt;br /&gt;Handy regular expression build, validation and testing tool.&lt;/p&gt;  &lt;h2&gt;OS Utilities &amp;amp; Application Freebies &lt;/h2&gt;  &lt;p&gt;&lt;strong&gt;Virtual Clone Drive &lt;/strong&gt;&lt;a href="http://www.slysoft.com/en/virtual-clonedrive.html"&gt;http://www.slysoft.com/en/virtual-clonedrive.html&lt;/a&gt;    &lt;br /&gt;Incredibly useful iso mounting utility that allows you to instantly mount any iso into a drive.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Auslogics Disk Defrag&lt;/strong&gt; &lt;a href="http://www.auslogics.com/disk-defrag"&gt;http://www.auslogics.com/disk-defrag&lt;/a&gt;     &lt;br /&gt;Very nice free disk defrag app to replace the base Windows version (works in Windows 7.)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Notepad++&lt;/strong&gt; &lt;a href="http://notepad-plus.sourceforge.net/uk/site.htm"&gt;http://notepad-plus.sourceforge.net/uk/site.htm&lt;/a&gt;     &lt;br /&gt;AWESOME little app for editing XML, HTML, etc.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Windows Live Writer&lt;/strong&gt; &lt;a href="http://download.live.com/writer"&gt;http://download.live.com/writer&lt;/a&gt;     &lt;br /&gt;Best blog post authoring application I have found.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;7Zip&lt;/strong&gt; &lt;a href="http://www.7-zip.org/"&gt;http://www.7-zip.org/&lt;/a&gt;     &lt;br /&gt;Nice compression / extraction utility.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;WinDirStat&lt;/strong&gt; &lt;a href="http://windirstat.info/"&gt;http://windirstat.info/&lt;/a&gt;     &lt;br /&gt;Easy and visual way to figure out where all of your hard disk space has gone.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Picasa&lt;/strong&gt; &lt;a href="http://picasa.google.com/"&gt;http://picasa.google.com/&lt;/a&gt;     &lt;br /&gt;Incredible useful photo and video management app.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Paint.NET&lt;/strong&gt; &lt;a href="http://www.getpaint.net/"&gt;http://www.getpaint.net/&lt;/a&gt;     &lt;br /&gt;Sweet Photoshop Lite replacement (FREE!).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Digsby&lt;/strong&gt; &lt;a title="http://www.digsby.com" href="http://www.digsby.com"&gt;http://www.digsby.com&lt;/a&gt;     &lt;br /&gt;Excellent IM client that supports every protocol under the sun.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;FoxIt Reader&lt;/strong&gt; &lt;a href="http://www.foxitsoftware.com/pdf/reader/"&gt;http://www.foxitsoftware.com/pdf/reader/&lt;/a&gt;     &lt;br /&gt;Lightweight PDF reader.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Virtual Box&lt;/strong&gt; &lt;a href="http://www.virtualbox.org/"&gt;http://www.virtualbox.org/&lt;/a&gt;     &lt;br /&gt;Most excellent virtualization application. Puts Virtual PC to shame.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Google Analytics&lt;/strong&gt; &lt;a href="http://www.google.com/analytics/"&gt;http://www.google.com/analytics/&lt;/a&gt;     &lt;br /&gt;Super awesome analytics for all of your web applications.&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/_Gf61CHy560" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/8154708446522135198/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=8154708446522135198" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8154708446522135198?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8154708446522135198?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/_Gf61CHy560/essential-free-software-for-net.html" title="Essential Free Software For .NET Developers" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.schnieds.com/2010/01/essential-free-software-for-net.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0QNRHc8eSp7ImA9WxJUFUQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-8907222042644562680</id><published>2009-07-14T12:22:00.000-07:00</published><updated>2009-07-14T12:23:15.971-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-14T12:23:15.971-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><title>ASP.NET Session Expiration Redirect</title><content type="html">&lt;p&gt;Most of the applications I work with require some form of authentication and a timed expiration of the authentication ticket and session object. When the expiration takes place it can wreak havoc on your application code if you are relying on the Session object or have authentication code in place to ensure that the user is authenticated before you serve up any data for them. &lt;/p&gt;  &lt;p&gt;Unfortunately ASP.NET doesn't provide a nice out of the box solution for handling the session timeout gracefully. Everything expires behind the scenes and your user is left unaware of what has happened. Additional problems can arise if the user abandoned their browser in a state that you didn't code for, which can result in errors or exceptions taking place. &lt;/p&gt;  &lt;p&gt;With this in mind I like to put a Session Expired page in place in my applications and pro-actively send the user there when their session ends. This accomplishes a few different things: &lt;/p&gt;  &lt;p&gt;1) Provides a nice user experience for your users    &lt;br /&gt;2) Prevents your application from being left in an unknown state when the session / auth ticket expires     &lt;br /&gt;3) Prevents application errors and exceptions from occurring when a user tries to perform an action on a page after their session / auth ticket has expired &lt;/p&gt;  &lt;h3&gt;Nested MasterPage(s) For All Authenticated Pages &lt;/h3&gt;  &lt;p&gt;You need to implement a MasterPage (or a Page base class) for all of your authenticated pages so you can inject a bit of javascript to handle the redirect on session timeout.&lt;/p&gt;  &lt;h3&gt;Get Your Web.config Settings Straight &lt;/h3&gt;  &lt;p&gt;Make sure that your auth ticket timeout and session timeout match. &lt;/p&gt;  &lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;&amp;lt;!-- &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        Session configuration &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        - Timeout value needs to match Forms Auth timeout** &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    --&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;sessionState&lt;/span&gt; &lt;span style="color: #ff0000"&gt;timeout&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;45&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    &lt;span style="color: #008000"&gt;&amp;lt;!-- &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        The &amp;lt;authentication&amp;gt; section enables configuration &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        of the security authentication mode used by &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;        ASP.NET to identify an incoming user. &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;    --&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;authentication&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mode&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Forms&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;forms&lt;/span&gt; &lt;span style="color: #ff0000"&gt;loginUrl&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Login.aspx&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;protection&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;All&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;path&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;/&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;requireSSL&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;timeout&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;45&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;.ASPXAUTH&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;slidingExpiration&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;true&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;defaultUrl&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Login.aspx&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;cookieless&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;UseDeviceProfile&amp;quot;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;           &lt;span style="color: #ff0000"&gt;enableCrossAppRedirects&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.web&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Create Your Session Expiration Page &lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Create a page for your users to be taken to when their session expires. I created SessionExpired.aspx with the following message: &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Session Expired&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h2&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;                   &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;color:White;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Your session has expired due to inactivity.&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;span&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;br&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;br&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt; &lt;span style="color: #ff0000"&gt;href&lt;/span&gt;=&lt;span style="color: #0000ff"&gt;&amp;quot;Login.aspx&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;Click here to login again&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;a&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;p&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt; &lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Ensure the Authentication ticket is signed out in your code behind:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;FormsAuthentication.SignOut();&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Add The Session Expiration Javascript To Your Page_Load&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;In the Page_Load method of your MasterPage (or base page class) add the following code: &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 650px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;&lt;span style="color: #008000"&gt;// Handle the session timeout &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;string&lt;/span&gt; sessionExpiredUrl = Request.Url.GetLeftPart(UriPartial.Authority) + &amp;quot;&lt;span style="color: #8b0000"&gt;/SessionExpired.aspx&lt;/span&gt;&amp;quot;; &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;StringBuilder script = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringBuilder(); &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;script.Append(&amp;quot;&lt;span style="color: #8b0000"&gt;function expireSession(){ \n&lt;/span&gt;&amp;quot;); &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;script.Append(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color: #8b0000"&gt; window.location = '{0}';\n&lt;/span&gt;&amp;quot;, sessionExpiredUrl)); &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;script.Append(&amp;quot;&lt;span style="color: #8b0000"&gt;} \n&lt;/span&gt;&amp;quot;); &lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,&amp;#39;Courier New&amp;#39;,courier,monospace; font-size: 12px"&gt;script.Append(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Format(&amp;quot;&lt;span style="color: #8b0000"&gt;setTimeout('expireSession()', {0}); \n&lt;/span&gt;&amp;quot;, &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Session.Timeout * 60000)); &lt;span style="color: #008000"&gt;// Convert minutes to milliseconds &lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre style="background-color: #fbfbfb; 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;.Page.ClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.GetType(), &amp;quot;&lt;span style="color: #8b0000"&gt;expirescript&lt;/span&gt;&amp;quot;, script.ToString(), &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;That's It &lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The session timeout script should be injected into each of your authenticated pages now. The client's browser will begin the countdown after each page has loaded or each PostBack has occurred. Once the countdown is reached the browser will redirect to your SessionExpired page. &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Reference: &lt;br /&gt;  &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/shahed/archive/2007/09/05/redirect-to-login-page-on-session-expiration-asp-net.aspx"&gt;http://msmvps.com/blogs/shahed/archive/2007/09/05/redirect-to-login-page-on-session-expiration-asp-net.aspx&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Aaron Schnieder &lt;br /&gt;  &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/7rw3N_p4Jrw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/8907222042644562680/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=8907222042644562680" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8907222042644562680?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8907222042644562680?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/7rw3N_p4Jrw/aspnet-session-expiration-redirect.html" title="ASP.NET Session Expiration Redirect" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total><feedburner:origLink>http://www.schnieds.com/2009/07/aspnet-session-expiration-redirect.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIDRH04fyp7ImA9WxJRGEU.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-3664969808320170145</id><published>2009-05-20T23:22:00.000-07:00</published><updated>2009-05-20T23:32:55.337-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-20T23:32:55.337-07:00</app:edited><title>The Power (and complexity) Of .NET Unit Testing</title><content type="html">I have recently begun a journey down the path of unit testing. I have been engineering software for many years now and up until this point my testing has been limited to integration testing my code using a front end. While this type of testing is effective in certain instances, it is not thorough and leaves a lot of unconvered bugs. I am part of a very strong engineering team at the moment and one of the software design techniques they swear by is unit testing. As I learn more and more about unit testing the more I am sold on this concept.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Where To Begin&lt;/span&gt;&lt;br /&gt;I purchased "The Art of Unit Testing" by Roy Osherove to get my head wrapped around this new software design paradigm; this book is awesome. A great book that covers the basics, the concepts, the theory as well as the application in real world scenarios. I highly recommend you get this book: http://www.manning.com/osherove/&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Unit Testing Aids&lt;/span&gt;&lt;br /&gt;Unit testing takes time to engineer, no doubt about it. However there are a number of great software packages that will make your unit testing life a lot easier. Whatever unit testing framework you end up choosing needs a good mocking framework to co-incide with it. With that in mind let me suggest TypeMock.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;TypeMock Isolator&lt;/span&gt; - Aiding your ASP.NET unit testing efforts&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.typemock.com/"&gt;Unit Testing&lt;/a&gt; ASP.NET? &lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php"&gt;ASP.NET unit testing&lt;/a&gt; has never been this easy.&lt;br /&gt;&lt;br /&gt;Typemock is launching a new product for ASP.NET developers – the &lt;strong&gt;ASP.NET Bundle&lt;/strong&gt; - and for the launch will be giving out &lt;span style="color: rgb(0, 102, 0);"&gt;&lt;strong&gt;FREE licenses&lt;/strong&gt;&lt;/span&gt; to bloggers and their readers.&lt;br /&gt;&lt;br /&gt;The ASP.NET Bundle is the ultimate ASP.NET unit testing solution, and offers both &lt;a href="http://www.typemock.com/"&gt;Typemock Isolator&lt;/a&gt;, a &lt;a href="http://www.typemock.com/"&gt;unit test&lt;/a&gt; tool and &lt;a href="http://sm-art.biz/Ivonna.aspx"&gt;Ivonna&lt;/a&gt;, the Isolator add-on for &lt;a href="http://sm-art.biz/Ivonna.aspx"&gt;ASP.NET unit testing&lt;/a&gt;, for a bargain price.&lt;br /&gt;&lt;br /&gt;Typemock Isolator is a leading &lt;a href="http://www.typemock.com/"&gt;.NET unit testing&lt;/a&gt; tool (C# and VB.NET) for many ‘hard to test’ technologies such as &lt;a href="http://typemock.com/sharepointpage.php"&gt;SharePoint&lt;/a&gt;, &lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php"&gt;ASP.NET&lt;/a&gt;, &lt;a href="http://www.typemock.com/ASP.NET_unit_testing_page.php"&gt;MVC&lt;/a&gt;, &lt;a href="http://www.typemock.com/wcfpage.php"&gt;WCF&lt;/a&gt;, WPF, &lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;Silverlight&lt;/a&gt; and more. Note that for &lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;unit testing Silverlight&lt;/a&gt; there is an open source Isolator add-on called &lt;a href="http://www.typemock.com/Silverlight_unit_testing_page.php"&gt;SilverUnit&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The first 60 bloggers who will blog this text in their blog and &lt;a href="http://blog.typemock.com/2009/05/get-free-typemock-licenses-aspnet.html"&gt;tell us about it&lt;/a&gt;, will get a Free Isolator ASP.NET Bundle license (Typemock Isolator + Ivonna). If you post this in an ASP.NET &lt;strong&gt;dedicated&lt;/strong&gt; blog, you'll get a license automatically (even if more than 60 submit) during the first week of this announcement.&lt;br /&gt;&lt;br /&gt;Also 8 bloggers will get an &lt;strong&gt;additional 2 licenses&lt;/strong&gt; (each) to give away to their readers / friends.&lt;br /&gt;&lt;br /&gt;Go ahead, click the following link for &lt;a href="http://blog.typemock.com/2009/05/get-free-typemock-licenses-aspnet.html"&gt;more information &lt;/a&gt;on how to get your free license.&lt;br /&gt;&lt;br /&gt;Aaron&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/Tqh_Pul4f-E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/3664969808320170145/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=3664969808320170145" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3664969808320170145?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3664969808320170145?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/Tqh_Pul4f-E/power-and-complexity-of-net-unit.html" title="The Power (and complexity) Of .NET Unit Testing" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.schnieds.com/2009/05/power-and-complexity-of-net-unit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D04HQ3syeip7ImA9WxVaEUQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-1903485578016472512</id><published>2009-04-08T06:05:00.001-07:00</published><updated>2009-04-08T06:05:32.592-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-08T06:05:32.592-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><title>How To Register An ASP.NET Custom Control</title><content type="html">&lt;p&gt;If you write a custom ASP.NET control you need to register the control either on the &lt;strong&gt;Page&lt;/strong&gt; level or globally in your &lt;strong&gt;web.config&lt;/strong&gt; so you can use the control on forms in your web application.&lt;/p&gt;  &lt;h3&gt;ASP.NET Page Level Custom Control Declaration&lt;/h3&gt;  &lt;p&gt;If you want to register your control per page that you use it on, you can use the following declaration at the top of your web form:    &lt;br /&gt;&amp;lt;%@ Register TagPrefix=&amp;quot;myWebControls&amp;quot; Namespace=&amp;quot;My.Website.Controls&amp;quot; Assembly=&amp;quot;My.Website&amp;quot; %&amp;gt; &lt;/p&gt;  &lt;h3&gt;ASP.NET Site Level Custom Control Declaration&lt;/h3&gt;  &lt;p&gt;If you want to register your asp.net control(s) for you entire website you can use the following declaration in your web.config file:    &lt;br /&gt;&amp;lt;add tagPrefix=&amp;quot;myWebControls&amp;quot; namespace=&amp;quot;My.Website.Controls&amp;quot; assembly=&amp;quot;My.Website&amp;quot;/&amp;gt;&lt;/p&gt;  &lt;h3&gt;Parser Error Message: Unknown server tag&lt;/h3&gt;  &lt;p&gt;If you pre-compile our web application and do not specify the assembly in your control declaration you will get the following error when trying to use your ASP.NET custom control:    &lt;br /&gt;&lt;strong&gt;Parser Error Message: Unknown server tag&lt;/strong&gt; 'myWebControls:ViewEditTextControl'. &lt;/p&gt;  &lt;p&gt;Aaron Schnieder    &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/kdvYicDPNWQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/1903485578016472512/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=1903485578016472512" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/1903485578016472512?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/1903485578016472512?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/kdvYicDPNWQ/how-to-register-aspnet-custom-control.html" title="How To Register An ASP.NET Custom Control" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.schnieds.com/2009/04/how-to-register-aspnet-custom-control.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0AARH47cSp7ImA9WxVUGUQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-6050002270667704889</id><published>2009-03-24T09:21:00.001-07:00</published><updated>2009-03-25T08:42:25.009-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-25T08:42:25.009-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><title>LINQ vs FOREACH vs FOR Loop Performance</title><content type="html">&lt;p&gt;I made a blatantly stupid logic mistake the other day in a business logic layer method that I was writing and got the following exception: “&lt;strong&gt;Collection was modified; enumeration operation may not execute.&lt;/strong&gt;” The problem what I was trying to remove an object from a collection while I was enumerating through it using a FOREACH statement. After I realized what I had done I solved the problem by populating a new collection with a little bit of LINQ.&lt;/p&gt;  &lt;div   style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;   &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;     &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   1:&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;// Get the original list of values&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   2:&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&amp;gt; booleanValues = GetBooleanList(numberOfTests);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   3:&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;// Now create a new list containing the objects we want to remove &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   4:&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;// from the original list&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   5:&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&amp;gt; valuesToDelete_Linq = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;&amp;gt;(from b &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; booleanValues&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   6:&lt;/span&gt;                                                 &lt;span style="color: rgb(0, 0, 255);"&gt;where&lt;/span&gt; !b&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   7:&lt;/span&gt;                                                 select b);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   8:&lt;/span&gt; &lt;span style="color: rgb(0, 128, 0);"&gt;// Now remove the values safely from the original list&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;   9:&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; b &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; valuesToDelete_Linq)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);"&gt;  10:&lt;/span&gt;     booleanValues.Remove(b);&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;There were several solutions I could have used to solve the problem; specifically I could have used a FOR loop, multiple FOREACH loops or the LINQ solution that I posted above (and there are probably more solutions that I haven’t thought of.) This led me to wonder about the performance for each solution, which in turn led me to this post: &lt;a title="http://frater.wordpress.com/2008/02/20/collection-was-modified-enumeration-operation-may-not-execute/" href="http://frater.wordpress.com/2008/02/20/collection-was-modified-enumeration-operation-may-not-execute/"&gt;http://frater.wordpress.com/2008/02/20/collection-was-modified-enumeration-operation-may-not-execute/&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;FOR – FOREACH – LINQ Performance Tests&lt;/h3&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;My system specs:&lt;/span&gt;&lt;br /&gt;- Intel Core 2 Duo 2.5 GHz&lt;br /&gt;- 4 GB memory&lt;br /&gt;- Windows Vista Enterprise 64bit&lt;br /&gt;- .NET Framework 3.5 SP1&lt;br /&gt;&lt;p&gt;After reading through the post above and the comments that it was followed by, I decided to test all three solutions to see what the speed was like. The results surprised me by quite a lot. I knew LINQ was somewhat slow, but I didn’t realize exactly how slow until I ran these tests.&lt;/p&gt;&lt;br /&gt;&lt;div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;br /&gt;&lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;For Loop results: Bool Count = 2002, Time = 00:00:00.0060000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;Double For Each results: Bool Count = 2002, Time = 00:00:00.0760000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;LINQ results: Bool Count = 2002, Time = 00:00:00.0760000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;For Loop results: Bool Count = 20002, Time = 00:00:00.1380000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;Double For Each results: Bool Count = 20002, Time = 00:00:00.9780000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;LINQ results: Bool Count = 20002, Time = 00:00:00.9820000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;For Loop results: Bool Count = 200002, Time = 00:00:06.4100000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;Double For Each results: Bool Count = 200002, Time = 00:01:39.0640000&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;LINQ results: Bool Count = 200002, Time = 00:01:39.4220000&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;So yeah, LINQ is considerably slower than using a FOR loop in this instance. However, I would personally still use LINQ in instances where I am working with a small amount of data and the performance difference is negligible. Why? Because in my opinion LINQ is much easier to read, understand &amp;amp; lends itself to fewer bugs.&lt;/p&gt;&lt;br /&gt;&lt;h3&gt;Performance Test Application Download&lt;/h3&gt;&lt;p&gt;You can download and run the performance test that includes implementations of each solution I mentioned above from the link below.&lt;br /&gt;&lt;br /&gt;&lt;iframe style="border: 1px solid rgb(221, 229, 233); margin: 3px; padding: 0px; width: 240px; height: 66px; background-color: rgb(255, 255, 255);" marginwidth="0" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedrowdetail.aspx/Public/RemoveFromGenericListTest.zip" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Aaron Schnieder&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/mJIRvyVsiBc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/6050002270667704889/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=6050002270667704889" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6050002270667704889?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6050002270667704889?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/mJIRvyVsiBc/linq-vs-foreach-vs-for-loop-performance.html" title="LINQ vs FOREACH vs FOR Loop Performance" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total><feedburner:origLink>http://www.schnieds.com/2009/03/linq-vs-foreach-vs-for-loop-performance.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMHQ386eCp7ImA9WxVUFEw.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-3818516575460130344</id><published>2009-03-18T15:13:00.001-07:00</published><updated>2009-03-18T15:13:52.110-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-18T15:13:52.110-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bug fixes" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><title>CollapsiblePanelExtender Height with data controls</title><content type="html">&lt;p&gt;I recently ran into a problem where I need to use the AjaxControlToolkit CollapsiblePanelExtender to contain a GridView. The CollapsiblePanelExtender is inside an UpdatePanel and items can be added to the table that drives the GridView within the CollapsiblePanelExtender. After a new item was added to the SQL table and then databound to the GridView, the CollapsiblePanelExtender height would not adjust to account for the new rows. &lt;/p&gt;  &lt;p&gt;This problem was driving me nuts until I found the answer in the ASP.NET Forums. All you need to do is wrap your databound control(s) in an asp:Panel or Div with the following style attribute:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;style=&amp;quot;overflow: hidden;&amp;quot;&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Adding that tag will take care of the problem and the CollapsiblePanelExtender will adjust to the proper height.&lt;/p&gt;  &lt;p&gt;Example:&lt;/p&gt;  &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;   &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;     &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdatePanel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;clpsUpdatePanel&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;UpdateMode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Conditional&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlTitle&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;padding: 1px; cursor: pointer; vertical-align: middle;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                    This is my collapsible panel title&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;collapseImage&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;SkinID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;TipGreen&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;h1&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;div&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;                      &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #008000"&gt;&amp;lt;!--Panel with style=&amp;quot;overflow: hidden;&amp;quot; will ensure the CollapsiblePanelExtender will display &lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #008000"&gt;            the contents of a databound control after PostBack --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlDataBoundControl&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Height&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;100%&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;overflow: hidden;&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:GridView&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;grdvwExcludedAffiliates&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                  &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                  &lt;span style="color: #ff0000"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;True&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                  &lt;span style="color: #ff0000"&gt;DataSourceID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;odsMyData&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:GridView&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:ObjectDataSource&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;odsMyData&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #ff0000"&gt;OldValuesParameterFormatString&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;original_{0}&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #ff0000"&gt;SelectMethod&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;GetMyData&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #ff0000"&gt;TypeName&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;BusinessLogic.MyLogic&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;SelectParameters&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Parameter&lt;/span&gt; &lt;span style="color: #ff0000"&gt;DefaultValue&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;0&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Id&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;Type&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Int32&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;SelectParameters&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:ObjectDataSource&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdateProgress&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;updProgress&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;AssociatedUpdatePanelID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;clpsUpdatePanel&amp;quot;&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ProgressTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;                    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Image&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;prgImage&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;SkinID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Spinner&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;                &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ProgressTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdateProgress&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;ajaxToolkit:CollapsiblePanelExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;ID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlExtender&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Server&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;TargetControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlDataBoundControl&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;ExpandControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlTitle&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;CollapseControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;pnlTitle&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;Collapsed&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;False&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;ImageControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;collapseImage&amp;quot;&lt;/span&gt;  &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;ExpandedImage&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;~/Images/arrowdown.gif&amp;quot;&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;CollapsedImage&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;~/Images/arrow.gif&amp;quot;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;            &lt;span style="color: #ff0000"&gt;SuppressPostBack&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;ContentTemplate&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;    &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:UpdatePanel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;- Aaron Schnieder &lt;br /&gt;  &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/JNMRF5gb2AM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/3818516575460130344/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=3818516575460130344" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3818516575460130344?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/3818516575460130344?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/JNMRF5gb2AM/collapsiblepanelextender-height-with.html" title="CollapsiblePanelExtender Height with data controls" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.schnieds.com/2009/03/collapsiblepanelextender-height-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcBSX8-eCp7ImA9WxVUE0w.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-7848367277479092149</id><published>2009-03-17T10:00:00.000-07:00</published><updated>2009-03-17T10:47:38.150-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-17T10:47:38.150-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title>Creating a SQL Exclusion Table Using LEFT JOIN</title><content type="html">&lt;p&gt;For a current project I needed to create a table that contained a list of exclusions that should be filtered out from another table when a specific set of criteria were met. This is a pretty common scenario where you have a large table of data and you want to be able to provide the ability through a user interface for a user to filter the data using an exclusion list.&lt;/p&gt;  &lt;p&gt;I have access to an amazing SQL guru, Peter Loos, who was able to help me brainstorm the best approach for altering existing stored procedures to include a filter for information included in the new exclusion table I added for this feature. During the course of speaking with Peter I learned the following:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;!= operator is being deprecated, we need to use &amp;lt;&amp;gt; from here on out.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;TSQL NOT IN performance sucks; a JOIN should be used in place of NOT IN if at all possible.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;My initial solution was do modify the existing stored procedures which returned the list that I needed to filter with my exclusion table by adding a WHERE clause that included a NOT IN (SELECT…) statement. After speaking with Peter it became clear that NOT IN could cause performance problems down the road, so I went down the path of figuring out how to do this with a JOIN statement.&lt;/p&gt;  &lt;h3&gt;Example Exclusion Table&lt;/h3&gt;  &lt;p&gt;In this example of how to setup an exclusion table in SQL, we will use an address book example. Lets say I have an address book of all of the people I know and their contacts like the following:&lt;/p&gt;  &lt;h4&gt;AddressBook Table&lt;/h4&gt;  &lt;p&gt;&lt;strong&gt;SQL Table Definition&lt;/strong&gt;&lt;/p&gt;  &lt;div   style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;   &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;     &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;TABLE&lt;/span&gt; #AddressBook(AddressBookId &lt;span style="color: rgb(0, 0, 255);"&gt;INT&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;KEY&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;                            ,FullName &lt;span style="color: rgb(0, 0, 255);"&gt;varchar&lt;/span&gt;(100) &lt;span style="color: rgb(0, 0, 255);"&gt;NULL&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;                            ,Phone &lt;span style="color: rgb(0, 0, 255);"&gt;varchar&lt;/span&gt;(20)    &lt;span style="color: rgb(0, 0, 255);"&gt;NULL&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;                            ,Location &lt;span style="color: rgb(0, 0, 255);"&gt;varchar&lt;/span&gt;(200) &lt;span style="color: rgb(0, 0, 255);"&gt;NULL&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (1, &lt;span style="color: rgb(0, 96, 128);"&gt;'Jack Bauer'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'853-234-5968'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'Los Angeles, CA'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (2, &lt;span style="color: rgb(0, 96, 128);"&gt;'John Stewart'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'451-856-4468'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'New York, NY'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (3, &lt;span style="color: rgb(0, 96, 128);"&gt;'Jim Cramer'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'452-938-7228'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'New York, NY'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (4, &lt;span style="color: rgb(0, 96, 128);"&gt;'Stephen Colbert'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'451-467-3333'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'New York, NY'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (5, &lt;span style="color: rgb(0, 96, 128);"&gt;'Bernie Madoff'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'609-611-4468'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;'Federal Prison, PA'&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; * &lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; #AddressBook&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Resultset&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QQqEHtDW18M/Sb_TYCeEKxI/AAAAAAAAAGI/LNqx1vA6dqQ/s1600-h/image3.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="http://lh6.ggpht.com/_QQqEHtDW18M/Sb_TYbyFfQI/AAAAAAAAAGM/PfkW0dNlyW8/image_thumb1.png?imgmax=800" border="0" height="184" width="644" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;NotMyFriends Table&lt;/h4&gt;&lt;p&gt;Now lets say I want to filter my address book down to a list of just people I consider my friends, so I create an exclusion table and enter those contacts that I DON’T consider to be friends.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL Table Definition&lt;/strong&gt;&lt;/p&gt;&lt;div   style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt; &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;CREATE&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;TABLE&lt;/span&gt; #NotMyFriends(NotMyFriendsId &lt;span style="color: rgb(0, 0, 255);"&gt;INT&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;PRIMARY&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;KEY&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;                            ,AddressBookId &lt;span style="color: rgb(0, 0, 255);"&gt;INT&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #NotMyFriends &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (1,3)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;INSERT &lt;span style="color: rgb(0, 0, 255);"&gt;INTO&lt;/span&gt; #NotMyFriends &lt;span style="color: rgb(0, 0, 255);"&gt;VALUES&lt;/span&gt; (2,5)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; * &lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; #NotMyFriends&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Resultset&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QQqEHtDW18M/Sb_TYjWaKQI/AAAAAAAAAGQ/PYiutHntLQg/s1600-h/image6.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="http://lh3.ggpht.com/_QQqEHtDW18M/Sb_TYmV5IGI/AAAAAAAAAGU/rt7ZkXVK-ro/image_thumb2.png?imgmax=800" border="0" height="77" width="244" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h3&gt;Filtered Resultset&lt;/h3&gt;&lt;p&gt;So the end goal of creating the NotMyFriends exclusion table is to be able to filter the AddressBook table, removing anyone listed in the NotMyFriends table so my final resultset is a list of contact information for just my friends.&lt;/p&gt;&lt;h4&gt;NOT IN Solution&lt;/h4&gt;&lt;p&gt;The first way I thought of doing this was to use a NOT IN statement, which filtered the results just like I wanted. The only problem with this solution (as I learned from Peter Loos) was the NOT IN statement performance sucks.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL NOT IN Query&lt;/strong&gt;&lt;/p&gt;&lt;div   style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt; &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; * &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;AS&lt;/span&gt; MyFriends&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;WHERE&lt;/span&gt; MyFriends.AddressBookId &lt;span style="color: rgb(0, 0, 255);"&gt;NOT&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;IN&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; AddressBookId &lt;span style="color: rgb(0, 0, 255);"&gt;from&lt;/span&gt; #NotMyFriends)&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Resultset&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QQqEHtDW18M/Sb_TYw_bsFI/AAAAAAAAAGY/b0f4mnLooVo/s1600-h/image10.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="http://lh5.ggpht.com/_QQqEHtDW18M/Sb_TZbUE4cI/AAAAAAAAAGc/DIUkb00IFkQ/image_thumb4.png?imgmax=800" border="0" height="156" width="644" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;h4&gt;JOIN Solution&lt;/h4&gt;&lt;p&gt;So now I wanted the exact same results as I got using the NOT IN statement, but I want to use a JOIN instead to improve the performance of my query.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL JOIN Query&lt;/strong&gt;&lt;/p&gt;&lt;div   style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt; &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;SELECT&lt;/span&gt; * &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;FROM&lt;/span&gt; #AddressBook &lt;span style="color: rgb(0, 0, 255);"&gt;AS&lt;/span&gt; MyFriends&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" color="white" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;LEFT&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;JOIN&lt;/span&gt; #NotMyFriends&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;ON&lt;/span&gt; MyFriends.AddressBookId = #NotMyFriends.AddressBookId&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Resultset&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/_QQqEHtDW18M/Sb_TZowGYfI/AAAAAAAAAGg/8Z7r7XrbvUc/s1600-h/image14.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="http://lh3.ggpht.com/_QQqEHtDW18M/Sb_TaPjf0UI/AAAAAAAAAGk/ooWq_GWBEW0/image_thumb6.png?imgmax=800" border="0" height="158" width="644" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;We are almost there, except the filter didn’t work. The LEFT JOIN combined our full table of addresses &amp;amp; our exclusion table list, but it didn’t filter the results. Looking at the results above we need to add a WHERE clause to our LEFT JOIN.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;SQL JOIN Query with  WHERE Clause&lt;/strong&gt;&lt;/p&gt;&lt;div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;br /&gt; &lt;div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;SELECT * &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);"&gt;FROM &lt;span style="color: rgb(0, 128, 0);"&gt;#AddressBook AS MyFriends&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;LEFT JOIN &lt;span style="color: rgb(0, 128, 0);"&gt;#NotMyFriends&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;ON MyFriends.AddressBookId = &lt;span style="color: rgb(0, 128, 0);"&gt;#NotMyFriends.AddressBookId&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;WHERE #NotMyFriends.AddressBookId IS NULL&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;strong&gt;Resultset&lt;/strong&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/_QQqEHtDW18M/Sb_TatO4H3I/AAAAAAAAAGo/msOIUTQW5zE/s1600-h/image20.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="http://lh3.ggpht.com/_QQqEHtDW18M/Sb_TbLQDYHI/AAAAAAAAAGs/1qJIsfMDKv4/image_thumb10.png?imgmax=800" border="0" height="97" width="644" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Query Script Example Download&lt;/p&gt;&lt;p&gt;As you can see, the final SQL JOIN query that included the WHERE clause gets us the filtered results we wanted from the exclusion table contents and performs well to. &lt;/p&gt;&lt;p&gt;I created a sample TSQL script that uses temp tables to demonstrate the queries I posted above. You can download it here:&lt;br /&gt;&lt;br /&gt;&lt;iframe style="border: 1px solid rgb(221, 229, 233); margin: 3px; padding: 0px; width: 240px; height: 66px; background-color: rgb(255, 255, 255);" marginwidth="0" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedrowdetail.aspx/Public/SQLTableExclusionExampleQuery.sql" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Aaron Schnieder&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/LTKrdmshOQY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/7848367277479092149/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=7848367277479092149" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/7848367277479092149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/7848367277479092149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/LTKrdmshOQY/creating-sql-exclusion-table-using-left.html" title="Creating a SQL Exclusion Table Using LEFT JOIN" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/_QQqEHtDW18M/Sb_TYbyFfQI/AAAAAAAAAGM/PfkW0dNlyW8/s72-c/image_thumb1.png?imgmax=800" height="72" width="72" /><thr:total>3</thr:total><feedburner:origLink>http://www.schnieds.com/2009/03/creating-sql-exclusion-table-using-left.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEQCRHkzcCp7ImA9WxVVEU4.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4889767365467583729</id><published>2009-03-03T19:00:00.001-08:00</published><updated>2009-03-03T19:12:45.788-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-03T19:12:45.788-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>The keys to successfully delivering software</title><content type="html">&lt;p&gt;I have been developing and delivering software for over 10 years now and I have learned a few things along the way. I am not the smartest developer, the most elegant engineer or a hardcore software design geek. I have however had a good deal of success delivering software that meets business requirements on time and learned what works and what doesn’t along the way. In this post I will share with you what I have learned that works well and what routinely causes failure.&lt;/p&gt;  &lt;h2&gt;Extremes lead to failure&lt;/h2&gt;  &lt;p&gt;Let me warn you in advance of a theme that you are going find throughout this post; avoid extremes. This is a general principle in life that applies heavily to successful software development. For example, there is nothing wrong with alcohol in moderation. However, if your goal in life it is get hammered at any possible opportunity you are going to watch your life go down the drain. Cheeseburgers are great, they are yummy and one of man’s greatest inventions. However, if you hit up In-N-Out every day for lunch and throw down a couple of double-doubles you aren’t going to be a happy camper after a while. The same basic principles apply to successfully delivering software, you need healthy moderation in all areas of the process.&lt;/p&gt;  &lt;h2&gt;Cut out the cancer&lt;/h2&gt;  &lt;p&gt;You need to have a good engineering team. Now the definition of a good team can very widely, but here is my take. You need a group of engineers that are good at what they do, have interpersonal skills, can communicate, check their egos at the door and all share the common goal of delivering quality software that meets the business needs on time. If you have engineers on the team that are a cancer to your success you need to figure out how to deal with them rather than avoid them or mitigate them and hope the problem goes away.&lt;/p&gt;  &lt;p&gt;One of the common engineering cancers is the apathetic engineer. This is the engineer that comes in, does just enough not to get fired and looks for every opportunity to do anything other than work. The apathetic engineer will drag down those they work with and will make the rest of the team of engineers who are working hard angry.&lt;/p&gt;  &lt;p&gt;The other common engineering cancer I have seen on teams is the ego engineer. This is the engineer that feels they are the apex of software development and no one before them or after them will ever be as good. The ego engineer is a poison to the team and most of the other engineers will avoid working with this person like the plague. They aren’t part of the team, they are an island and almost always are more talk than substance.&lt;/p&gt;  &lt;p&gt;Your engineering team needs to gel well, with strengths and weakness complimenting each other. It is also very important that your team enjoy working together and respect each other. If your team hates to work with each other and there is disrespect within the group they will not perform well. Remove any cancer that exists and when you add new team members make sure that they are the right team fit.&lt;/p&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;&lt;/h2&gt;  &lt;h2&gt;Success Starts with good requirements&lt;/h2&gt;  &lt;p&gt;You can successfully deliver good software on time without good requirements, but it isn’t easy. Again, you don’t need an extreme here. You don’t need your marketing/product group to spend months and months and months analyzing requirements and debating over little nuances only to deliver the best set of requirements ever written two weeks before the year long project is due. &lt;/p&gt;  &lt;p&gt;On the other end of the spectrum are back of the napkin requirements. I had a product guy once that would go to bars, get drunk and then write out all of our “requirements” on the back of a napkin while he was hammered. He insisted that we should be able to successfully build any complex application with no more input that what he was able to scribble on a napkin while inebriated. As you can imagine, this end of the extreme didn’t work out too well either.&lt;/p&gt;  &lt;p&gt;You don’t need perfect requirements, but you need good requirements. Good requirements are well thought through, documented well enough that engineers can understand what the business needs are by reading them and have actionable requests. Wireframes, mockups and user experience scenarios are also very helpful to put into requirements.&lt;/p&gt;  &lt;h2&gt;don’t under or over engineer&lt;/h2&gt;  &lt;p&gt;Ah, now that you have a good team in place and you have some requirements you can work with here comes the fun part, actual engineering. Unfortunately it is still pretty easy to fail the actually software development part of the process even if you have a good team and solid requirements. Successfully delivering software from an engineering point of view requires that engineers be utilized effectively and over or under engineering is not allowed to be part of the process.&lt;/p&gt;  &lt;p&gt;Under engineering is otherwise known as hacking or spaghetti code. This is where your engineer’s only concern is getting the feature “done” and they have no concern for how it is done. Common excuses here are that “the requirements are changing all the time”, “we just had to get something in there”, “lets just get it working and refactor it after the fact”, etc., etc., etc. Hacking crappy code together never works out well. Even if you can hack features in to a working state, this approach will lead to tons of bugs and doesn’t create a foundation that you can build upon for future features and enhancements.&lt;/p&gt;  &lt;p&gt;Over engineering is a little bit trickier than hacking. Hacking is generally considered “bad” by most engineers and you won’t get much push back if you bring it up as a problem. Over engineering on the other hand is commonly accepted and viewed as good work because the theories and design being applied are all generally good software development. The problem here is that if you spend all of your time writing the most awesome, perfect, beautiful, slick, lovely, sweet, hotness widget you will probably never deliver anything at all, let alone on time. Software needs to be designed well, but if it is over engineered, overly complex and plans too far ahead in the future it is like spending the time to lay the foundation for a skyscraper when all you need to build is a single story house that you might want to add a room on to later on. Over engineering can be just as big of a problem as hacking because at the end of the day you still don’t end up with that you need to be successful.&lt;/p&gt;  &lt;p&gt;Balance is once again the key to success. Don’t hack, but also don’t spend so much time trying to put together the ultimate software design for what you need that you don’t get anywhere. Come up with solid designs that are flexible and are forward thinking, but keep them within the scope of the requirements and apply KISS (keep it simple stupid) as much as humanely possible. Make things only as complex as they need to be, comment your code and keep on alert for engineering scope creep as well as project scope creep.&lt;/p&gt;  &lt;h2&gt;How does this apply to .NET development specifically?&lt;/h2&gt;  &lt;p&gt;These basic principles apply to successful software development in any language on any platform. However, from what I have seen .NET development is specifically prone to problems with under engineering. Because Visual Studio is such an awesome IDE and because Microsoft makes so many of the tasks so easy to complete in ASP.NET there is a tendency for developers to rely on the wizards and just brute force something that works into place. ASP.NET developers need to intimately understand the platform that they are developing on as well as understand best practices for general software design. &lt;/p&gt;  &lt;p&gt;I hate to say it, but a lot of the problems come from software developers that worked in previous Microsoft frameworks such as Visual Basic who “update” their skills by opening Visual Studio 2008 and starting to code. The .NET framework is vast and if you want to write successful software in .NET you need to understand &lt;strong&gt;a)&lt;/strong&gt; solid OOP software design principles and &lt;strong&gt;b)&lt;/strong&gt; the framework itself. If you don’t understand solid OOP design principles, you need to take some classes or update your knowledge with some good books to get the basics. If you don’t understand .NET, I would recommend that you read some of the Intro to the Framework books and take one of the foundational Microsoft tests. The tests aren’t perfect, but if you study for them and pass them I guarantee you will come out understand the .NET framework better than most.&lt;/p&gt;  &lt;h2&gt;How Do I proceed?&lt;/h2&gt;  &lt;p&gt;If you read through this post and identified some area(s) that your company is currently struggling in, the fix probably won’t be quick or simple. You are going to have to put together a plan of what needs to change and how it should change, get buy in from the right individuals and then slowly implement process changes or team changes that will fix any issues that you identify. It is hard work to get past process or team problems, but well worth it when your software cycle becomes easier and is successful on a frequent basis.&lt;/p&gt;  &lt;p&gt;Aaron    &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.schnieds.com%2f2009%2f03%2fkeys-to-successfully-delivering.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.schnieds.com%2f2009%2f03%2fkeys-to-successfully-delivering.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/zonw_3YHoFA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4889767365467583729/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4889767365467583729" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4889767365467583729?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4889767365467583729?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/zonw_3YHoFA/keys-to-successfully-delivering.html" title="The keys to successfully delivering software" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.schnieds.com/2009/03/keys-to-successfully-delivering.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUFSHk4eSp7ImA9WxVRFEQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-8173821808646291486</id><published>2009-01-20T16:20:00.000-08:00</published><updated>2009-01-20T16:20:19.731-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-20T16:20:19.731-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="LINQ" /><title>LINQ Tips &amp; Tricks - I Heart LINQ</title><content type="html">&lt;div&gt;Ok, I have to admit it; I heart LINQ... I have a man-crush on LINQ; if LINQ were a president it would be Baberaham LINQoln. Ok, that last one was pretty bad, but I have had that quote from Wayne's World floating around in my head for a while now and it had to come out sooner or later. :)&lt;br /&gt;&lt;br /&gt;When I first heard about LINQ at a big Microsoft launch event I thought it was crap. The developer evangelist showed how you can generate inline SQL statements using LINQ and left it at that. My first thought was "great, a technology that takes us back to the stone ages of SQL development where developers don't put any thought into their database queries." How wrong I was; LINQ is awesome and can be a huge benefit to a single developer working with a local database, enterprise developers using stored procedures and developers not working with databases at all.&lt;br /&gt;&lt;br /&gt;I purchased the most excellent "&lt;a href="http://www.amazon.com/LINQ-Action-Fabrice-Marguerie/dp/1933988169/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1209337351&amp;amp;sr=8-1"&gt;LINQ in Action&lt;/a&gt;" book by Fabrice Marguerie, Steve Eichert &amp;amp; Jim Wooley; which I have been reading through in my spare time. If you are looking for a good resource to learn LINQ beyond the web I highly recommend this book. &lt;/div&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;br /&gt;&lt;div&gt;I have also been trying to use LINQ as much as possible in my development, as it is a huge time saver. Along the way I have learned a few tips &amp;amp; tricks for problems I needed to solve using LINQ which I will share with you below. I will follow up this post with other LINQ based posts including a couple of LINQ based ASP.NET controls that I am working on.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Prereqs&lt;/h3&gt;&lt;br /&gt;&lt;div&gt;Remember to include a reference to LINQ in your project as well as your class before trying to use LINQ or you are going to have some problems.&lt;br /&gt;C#: using System.Linq;&lt;br /&gt;VB.NET: Imports System.Linq&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Returning a Single Result from a LINQ Query&lt;/h2&gt;&lt;br /&gt;&lt;div&gt;So lets say that you want to use a LINQ query to return a single result. How do you do that?&lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt;string emailAddress = (from i in individuals&lt;br /&gt;where i.MemberID.Equals(individual.MemberID)&lt;br /&gt;select i.EmailAddress).Single();&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Using a LINQ Like % Query&lt;/h2&gt;&lt;br /&gt;&lt;div&gt;How do you write a query to search for a partial string match? Something like "WHERE s LIKE 'asdf%'&lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt;string myPartialSearchString = "Smit";&lt;br /&gt;var peoples = from i in individuals&lt;br /&gt;where i.LastName.Contains(myPartialSearchString)&lt;br /&gt;select i;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;Handling NULL Parameters in a LINQ Queries&lt;/h2&gt;&lt;br /&gt;&lt;div&gt;Lets say you have parameters(s) in your LINQ query where clause, how do you handle that?&lt;br /&gt;&lt;br /&gt;Here is an example:&lt;br /&gt;&lt;br /&gt;var peoples= from i in individuals&lt;br /&gt;where (string.IsNullOrEmpty(lastName) i.LastName.Equals(lastName))&lt;br /&gt;select i;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;The C# ?? null coalescing operator (and using it with LINQ)&lt;/h2&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2007/09/20/the-new-c-null-coalescing-operator-and-using-it-with-linq.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;h2&gt;101 LINQ Examples&lt;/h2&gt;&lt;br /&gt;&lt;div&gt;&lt;a href="http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx"&gt;http://msdn2.microsoft.com/en-us/vcsharp/aa336746.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;-Aaron&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com/&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/iFOvl1EUfHs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/8173821808646291486/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=8173821808646291486" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8173821808646291486?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8173821808646291486?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/iFOvl1EUfHs/linq-tips-tricks-i-heart-linq.html" title="LINQ Tips &amp; Tricks - I Heart LINQ" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2009/01/linq-tips-tricks-i-heart-linq.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CU4GSHY4eSp7ImA9WxRaE0s.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-4083620866569369190</id><published>2008-12-15T08:39:00.000-08:00</published><updated>2008-12-15T09:58:49.831-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-15T09:58:49.831-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>How Has The Recession Effected Developers?</title><content type="html">&lt;h3&gt;Poll&lt;/h3&gt;&lt;br /&gt;&lt;iframe frameborder="0" width="100%" height="550" src="http://www.micropoll.com/akira/MicroPoll?id=125743&amp;mode=html"&gt;&lt;/iframe&gt;&lt;div&gt;&lt;a href="http://www.micropoll.com/akira/mpview/518105-125743"&gt;View Poll&lt;/a&gt;&amp;nbsp;|&lt;a href="http://www.micropoll.com/akira/mpresult/518105-125743"&gt;View Results&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://www.micropoll.com"&gt;Polls&lt;/a&gt; PoweredBy &lt;a href="http://www.micropoll.com"&gt;MicroPoll&lt;/a&gt;&lt;/div&gt;&lt;img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMjkzNjA4NDA3MTQmcHQ9MTIyOTM2MDg1MzUyMCZwPTgwMDExJmQ9Jmc9MSZ*PSZvPTEwNDZmMGViMjFlMjQxZGRhY2Q3MjAzZDMwYzM*MTkz.gif" /&gt;&lt;br /&gt;&lt;h3&gt;Results&lt;/h3&gt;&lt;br /&gt;&lt;object width="450" height="300" &gt;&lt;param name="movie" value="http://www.micropoll.com/images/fusionchart/Bar2D.swf"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;param name="flashvars" value="debugMode=0&amp;dataURL=http://www.micropoll.com/akira/MicroPollChartData?id=125743"&gt;&lt;/param&gt;&lt;embed src="http://www.micropoll.com/images/fusionchart/Bar2D.swf" type="application/x-shockwave-flash" wmode="transparent" flashvars="debugMode=0&amp;dataURL=http://www.micropoll.com/akira/MicroPollChartData?id=125743" allowScriptAccess="always" width="450" height="300"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style="width:450px" align="right"&gt;&lt;a href="http://www.micropoll.com"&gt;Polls&lt;/a&gt; Powered By &lt;a href="http://www.micropoll.com"&gt;MicroPoll&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="float: left;"&gt;&lt;br /&gt;With all of the recession talk in the news, the daily massive layoffs that are taking place and the general doom &amp;amp; gloom feeling in the air I am very curious about how the recession has specifically effected developer's jobs. I have read many articles on CNN, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;MSNBC&lt;/span&gt;, etc. that have identified "computer programmer" positions as relatively safe jobs during this tough economic time. Have you found that to be true, are your jobs as developers relatively stable?&lt;br /&gt;&lt;br /&gt;I created the poll above to try to get an idea of what effect this recession is having on real people in the developer community. Please take time to categorize yourself as close as possible in the categories I have provided for the poll. Also, please make suggestions if you feel that other categories would be more helpful.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How I Have Been Effected&lt;/h3&gt;&lt;br /&gt;I am one of the lucky ones that found a new job during the recession (about 3 months ago now.) I was also able to sell a house and feel very blessed at this point. I make it a point to keep my skills up to date and to try to continue to improve. However, I still worry about the future and how hard it might be to find a new gig if necessary.&lt;br /&gt;&lt;br /&gt;Thanks for your responses and your time. Refer your developer friends to take the poll also, the more data the more useful this will be.&lt;br /&gt;&lt;br /&gt;Thanks!&lt;br /&gt;&lt;br /&gt;Aaron&lt;br /&gt;http://www.churchofficeonline.com&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f12%2fhow-has-recession-effected-developers.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f12%2fhow-has-recession-effected-developers.html" alt="kick it on DotNetKicks.com" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/CX3WpVx4d74" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/4083620866569369190/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=4083620866569369190" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4083620866569369190?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/4083620866569369190?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/CX3WpVx4d74/how-has-recession-effected-developers.html" title="How Has The Recession Effected Developers?" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.schnieds.com/2008/12/how-has-recession-effected-developers.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUFRns6fCp7ImA9WxRaEk4.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-8072197489325339093</id><published>2008-12-13T22:29:00.000-08:00</published><updated>2008-12-13T22:30:17.514-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-13T22:30:17.514-08:00</app:edited><title>Using Virtuals for Server Components in Development</title><content type="html">&lt;div&gt;&lt;span style="font-weight: bold;"&gt;Problem: &lt;/span&gt;&lt;br /&gt;As a developer it is almost a given that you need to run some sort of server resources (database, web server, etc.) to support your application development. You can run all of your necessary server components on your development machine, but doing this will hog your precious resources, clutter up your workstation and make standing up a new development machine if needed very time consuming.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution: &lt;/span&gt;&lt;br /&gt;Virtualization&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Virtual PC&lt;/h3&gt;&lt;br /&gt;&lt;div&gt;First off, I assume that you are familiar with virtual machines or virtual pcs. If not, it is basically the ability to run a fully contained separate OS within a shell on your local computer. For example, your host development machine might be running Windows XP or Windows Vista. You can create a virtual running Windows Server 2003, Linux, Vista, etc. that runs just like any other self contained application on your local host computer. Using virtuals is a very powerful development tool for any developer because it gives you easy access to testing environments, playing around with software installs without messing up your host box and in the context of this post, hosting server components that don't need to be on your local development host computer.&lt;/div&gt;&lt;br /&gt;&lt;h3&gt;Virtualization Software&lt;/h3&gt;&lt;br /&gt;&lt;div style="font-weight: bold;"&gt;Microsoft Virtual PC&lt;br /&gt;&lt;ul&gt;&lt;li style="font-weight: normal;"&gt;FREE&lt;/li&gt;&lt;li style="font-weight: normal;"&gt;Works fairly well&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: normal;"&gt;Windows only&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx"&gt;http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;VMWare Workstation (PC) or Fusion (Mac)&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Costs $$&lt;/li&gt;&lt;li&gt;Works EXCELLENT&lt;/li&gt;&lt;li&gt;Windows &amp;amp; Mac&lt;/li&gt;&lt;/ul&gt;&lt;a href="http://www.vmware.com/"&gt;http://www.vmware.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;- Aaron&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;br /&gt;&lt;div&gt; &lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/YSHgRJE0pX8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/8072197489325339093/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=8072197489325339093" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8072197489325339093?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/8072197489325339093?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/YSHgRJE0pX8/using-virtuals-for-server-components-in.html" title="Using Virtuals for Server Components in Development" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2008/12/using-virtuals-for-server-components-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkcESHs8fip7ImA9WxRWEkQ.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-393080703383301696</id><published>2008-10-29T07:58:00.000-07:00</published><updated>2008-10-29T08:26:49.576-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-29T08:26:49.576-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="TFS" /><title>Team Foundation Server (TFS) Installation Errors &amp; Fixes</title><content type="html">I have had the unfortunate pleasure of conducting three different Team Foundation Server - TFS - installations in the last couple of years. Each installation has been difficult to say the least and each installation has presented me with new &amp;amp; challenging errors. To benefit others who need to install TFS, this post is dedicated to TFS installation errors and how to fix them.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;If you have a TFS installation error &amp;amp; fix you would like me to add to this post, please put it in the comments and I will get it added ASAP. &lt;/span&gt;&lt;br /&gt;Hopefully this post can become a single valuable resource for TFS installation error troubleshooting.&lt;br /&gt;&lt;h2&gt;Before You Install&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;If you are upgrading, BACK UP EVERYTHING!!!!&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Follow the TFS installation guide STEP BY STEP; if you skip a step you are probably screwed (&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=FF12844F-398C-4FE9-8B0D-9E84181D9923&amp;amp;displaylang=en"&gt;you can find the guide here&lt;/a&gt;)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Setup the pre-requisite domain accounts TFSSETUP;TFSSERVICE;TFSREPORTS and use them as described in the TFS installation guide&lt;/li&gt;&lt;li&gt;MAKE SURE TFSSETUP is in the local Administrators groups on all TFS related servers&lt;br /&gt;&lt;/li&gt;&lt;li&gt;MAKE SURE you log in as TFSSETUP to perform ALL of the component installations&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;General Useful Information&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;The installation log files are stored in your account's temp folder, to view it just click on Start -&gt; Run and type %temp%&lt;/li&gt;&lt;li&gt;Delete all of the existing files in your temp directory before you attempt the TFS installation, this will make sure you can find the files you need&lt;/li&gt;&lt;li&gt;The TFS installation log of note is called VSMsiLog538C.txt or something similar&lt;/li&gt;&lt;li&gt;Create a .reg file in Notepad with the following lines and execute it before performing the installation to enable verbose TFS installation logging&lt;/li&gt;&lt;/ul&gt; &lt;p mce_keep="true"&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p mce_keep="true"&gt;Windows Registry Editor Version 5.00&lt;/p&gt; [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer]&lt;br /&gt;"EnableAdminTSRemote"=dword:00000001&lt;br /&gt;"Logging"="voicewarmup"&lt;/blockquote&gt;&lt;h2&gt;Reporting Services Related Errors&lt;/h2&gt;If you get any errors during TFS installation, use the following troubleshooting steps to make sure that Reporting Services is installed &amp;amp; functioning correctly.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open Internet Explorer and try to browse to http://yourservername&lt;yourservername&gt;/reports&lt;br /&gt;If this doesn't work, look in the Application log for errors and try to resolve those errors&lt;/yourservername&gt;&lt;/li&gt;&lt;li&gt;Open SQL Reporting Services Configuration utility&lt;br /&gt;Make sure that none the system checks are in error state&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;READ THIS&lt;/h3&gt;In my installation I resolved the errors with the fixes I have listed below and Reporting Services was running great. However, the TFS install would still fail and after I exited the installation Reporting Services would be broken. As it turns out the TFS install was changing Reporting Services configuration during the installation and breaking Reporting Services along the way!!! So here is what I did to fix it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make sure Reporting Services is working correct by visiting http://yourservername&lt;yourservername&gt;/reports in IE&lt;/yourservername&gt;&lt;/li&gt;&lt;li&gt;Start the TFS Install&lt;/li&gt;&lt;li&gt;When you get the Reporting Services error LEAVE THE INSTALL RUNNING&lt;/li&gt;&lt;li&gt;Go back and fix Reporting Services until you can successfully view http://yourservername&lt;yourservername&gt;/reports again&lt;/yourservername&gt;&lt;/li&gt;&lt;li&gt;Go back to the TFS Installer and click "Retry"; the install should work from there!!!&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Error: 28806&lt;/h2&gt;&lt;span style="font-weight: bold;"&gt;Cause #1:&lt;/span&gt;&lt;br /&gt;The TFS application pool should be running under the TFSSERVICE identity to provide the necessary security authorizations &amp;amp; identification.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fix #1:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open Internet Information Server Manager&lt;/li&gt;&lt;li&gt;Go into Application Pools&lt;/li&gt;&lt;li&gt;Right click on the Reporting Services application pool&lt;/li&gt;&lt;li&gt;Click on the Identity tab and change the identity to TFSSERVICE&lt;/li&gt;&lt;li&gt;Try the installation again&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Cause #2:&lt;/span&gt;&lt;br /&gt;Reporting Services database connection is currently set to SQL Login or Service Credentials. The connection needs to be using Windows Authentication.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fix #2:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open Reporting Services Configuration&lt;/li&gt;&lt;li&gt;Click on the Database Connection menu item on the left&lt;/li&gt;&lt;li&gt;Change the login type to Windows Authentication&lt;/li&gt;&lt;li&gt;Use the TFSSERVICE credentials to login&lt;/li&gt;&lt;li&gt;Try the installation again&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Error: 28805&lt;/h2&gt;&lt;span style="font-weight: bold;"&gt;Cause #1:&lt;/span&gt;&lt;br /&gt;The Reporting Services encryption key is being bad.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fix #1:&lt;/span&gt;&lt;br /&gt;For whatever reason sometimes the TFS install just doesn't like the Reporting Services Encryption Key that RS decided to generate. In these circumstances, Error 28805 can be fixed by doing the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Open Reporting Services Configuration&lt;/li&gt;&lt;li&gt;Click on the Encryption Keys menu item on the left&lt;/li&gt;&lt;li&gt;Backup the existing key to somewhere safe&lt;/li&gt;&lt;li&gt;Delete the encryption key&lt;/li&gt;&lt;li&gt;Try the installation again&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Error: 32000&lt;/h2&gt;&lt;span style="font-weight: bold;"&gt;Cause #1:&lt;/span&gt;&lt;br /&gt;During an upgrade scenario the schemas from the old version of TFS may have become corrupted somehow. The schema corruption is the root of the error and causing the installation to fail.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fix #1:&lt;/span&gt;&lt;br /&gt;Replace the corrupted schemas with good ones. This might require a call to Microsoft to get the uncorrupted schemas (I had to.)&lt;br /&gt;&lt;br /&gt;Hope this helps. &lt;span style="font-style: italic;"&gt;&lt;br /&gt;&lt;br /&gt;Remember, post your problems/solutions in the comments and I will add them to the list.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;- Aaron&lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f10%2fteam-foundation-server-tfs-installation.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f10%2fteam-foundation-server-tfs-installation.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/skXRbLO8db4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/393080703383301696/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=393080703383301696" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/393080703383301696?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/393080703383301696?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/skXRbLO8db4/team-foundation-server-tfs-installation.html" title="Team Foundation Server (TFS) Installation Errors &amp; Fixes" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2008/10/team-foundation-server-tfs-installation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkADRnc9cSp7ImA9WxRWEE8.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-6855753913565501167</id><published>2008-10-10T07:50:00.001-07:00</published><updated>2008-10-26T05:39:37.969-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-26T05:39:37.969-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="wcf" /><title>WCF BasicHttpBinding with Windows Authentication &amp; a 2.0 Client</title><content type="html">&lt;p&gt;Windows Authentication is a great way to provide authentication security in your WCF services. With the WSHttpEndpoing and a .NET 3.0+ client Windows Authentication works right out of the box with WCF, everything is just peachy. However, if you want to use the BasicHttpBinding for .NET 2.0 client backward compatibility then it is going to require a bit of configuration for both the clients &amp;amp; server.&lt;/p&gt;  &lt;p&gt;I covered the BasicHttpBinding in detail in &lt;a href="http://www.schnieds.com/2008/08/multiple-wcf-endpoints-net-20-clients.html" target="_blank"&gt;this post&lt;/a&gt;, I would recommend you check that out before you dive into specifically using Windows Authentication with the BasicHttpBinding.&lt;/p&gt;  &lt;h2&gt;Service Configuration&lt;/h2&gt;  &lt;p&gt;There are two areas that you need to focus on to enable Windows Authentication in a WCF service, the Web.config file &amp;amp; the service implementation.&lt;/p&gt;  &lt;h3&gt;Web.config Settings&lt;/h3&gt;  &lt;p&gt;All of the configuration for the Windows Authentication WCF BasicHttpBinding service takes place in the Web.config file. Here is exactly what you need:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Enable Windows Authentication &amp;amp; the Role Provider&lt;/strong&gt;&lt;/p&gt;  &lt;div&gt;   &lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;     &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;authentication&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;mode&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="Windows"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;&amp;lt;!-- Configure the Role Provider, Currently configured for Windows Tokens --&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;roleManager&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;enabled&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="true"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;defaultProvider&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="AspNetWindowsTokenRoleProvider"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Create The EndPoint&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;endpoint&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;address&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="basic"&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;binding&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="basicHttpBinding"&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;contract&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="IService"&lt;/span&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="WindowsAuthenticationBasicHttpBinding"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Configure the BasicHttpBinding Binding&lt;/strong&gt;&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;bindings&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;binding&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;name&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="WindowsAuthenticationBasicHttpBinding"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;security&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;mode&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="TransportCredentialOnly"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;                &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;transport&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;clientCredentialType&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="Windows"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;security&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;binding&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;basicHttpBinding&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;bindings&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;h3&gt;Service Implementation&lt;/h3&gt;&lt;p&gt;There are a couple of different ways you can do authentication for your WCF operations. I would highly recommend to base all of your authentication security on group or role membership rather than on single user access. Coding your operation authentication security in a role based manner will make administration of users allowed to access your operations much easier to manage in the future.&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Method 1: Operation Authentication Decoration&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Edit your service implementation class (Service.cs or similar) to include authentication decorations for your web operations.&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Declarative Role Based Security&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;[PrincipalPermission(SecurityAction.Demand, Role = OperationRoles.MyRoleName)]&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Method 2: Explicit Code Level Authentication&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Put the following code within your operation method to do explicit authentication in the actual method code.&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Programmatic Role Based Security&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre   style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!System.Threading.Thread.CurrentPrincipal.IsInRole(OperationRoles.MyRoleName))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; FaultException(&lt;span style="color: rgb(0, 96, 128);"&gt;"Unauthorized Exception"&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Full operation example code:&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Declarative Role Based Security&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);"&gt;[PrincipalPermission(SecurityAction.Demand, Role = OperationRoles.MyRoleName)]&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; GetData(&lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);"&gt;{&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Programmatic Role Based Security&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!System.Threading.Thread.CurrentPrincipal.IsInRole(OperationRoles.MyRoleName))&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; FaultException(&lt;span style="color: rgb(0, 96, 128);"&gt;"Unauthorized Exception"&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre    style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;font-family:consolas,'Courier New',courier,monospace;font-size:8pt;color:white;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// The user is authorized, so return back the data requested&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;.Format(&lt;span style="color: rgb(0, 96, 128);"&gt;"You entered: {0}"&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;value&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre face="consolas,'Courier New',courier,monospace" size="8pt" color="white" style="border-style: none; margin: 0em; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt;"&gt;}&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;h2&gt;Client Configuration&lt;/h2&gt;&lt;p&gt;The .NET 2.0 client needs to explicitly define the network credentials that are going to be sent across the wire. By default .NET 2.0 web references to web services don't pass credentials over the wire, which is why the explicit credential code is necessary. Here is how you need to configure your .NET 2.0 client to ensure your crendentials are passed across the wire and therefore allow you to be verified as a user in a valid role.&lt;/p&gt;&lt;div&gt;&lt;div   style="border-style: none; padding: 0px; overflow: visible; width: 100%; color: black; line-height: 12pt; background-color: rgb(244, 244, 244);font-family:consolas,'Courier New',courier,monospace;font-size:8pt;"&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Set the credentials to send across the wire to the WCF web service&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;ServiceRef.Service ws = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; WCFMultipleEndpointWinAuth2_0ClientWebApp.ServiceRef.Service();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: rgb(244, 244, 244);"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Use the default credentials, this can be set more specifically as needed&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;"&gt;ws.Credentials = System.Net.CredentialCache.DefaultCredentials;&lt;/pre&gt;&lt;br /&gt; &lt;/div&gt;&lt;/div&gt;&lt;h2&gt;Sample Code&lt;/h2&gt;&lt;p&gt;Here is a sample solution with service &amp;amp; client projects using the WCF BasicHttpBinding &amp;amp; Windows Authentication. &lt;/p&gt;&lt;p&gt;I have included the WCF Service with the authentication methods as well as a .NET 2.0 client configured to connect to the web service and pass appropriate credentials and a .NET 3.5 client configured to connect to the same web service for reference.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;NOTE: &lt;/strong&gt;In order to run the service, you will need to configure the service in IIS as a virtual directory at the following URI: http://localhost/WCFBasicEndpointWinAuth/Service.svc so Windows Authentication can be used. If you need help configuring IIS7 for ASP.NET/WCF development purposes &lt;a href="http://www.schnieds.com/2008/10/setting-up-iis7-in-vista-for-aspnet-wcf.html" target="_blank"&gt;refer to this post&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;iframe style="border: 1px solid rgb(221, 229, 233); margin: 3px; padding: 0px; width: 240px; height: 66px; background-color: rgb(255, 255, 255);" marginwidth="0" marginheight="0" src="http://cid-a62623415e09df8d.skydrive.live.com/embedrowdetail.aspx/Public/WCFMultipleEndpointsWindowsAuth.zip" scrolling="no" frameborder="0"&gt;&lt;br /&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;p&gt;Aaron&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/pX39u-fsUQA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/6855753913565501167/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=6855753913565501167" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6855753913565501167?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6855753913565501167?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/pX39u-fsUQA/wcf-basichttpbinding-with-windows.html" title="WCF BasicHttpBinding with Windows Authentication &amp;amp; a 2.0 Client" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2008/10/wcf-basichttpbinding-with-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUDSXY5fSp7ImA9WxRQFUs.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-7117326623930420582</id><published>2008-10-09T08:57:00.000-07:00</published><updated>2008-10-09T09:04:38.825-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-09T09:04:38.825-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IIS" /><category scheme="http://www.blogger.com/atom/ns#" term="asp.net" /><title>Setting Up IIS7 In Vista For ASP.NET / WCF Development Purposes</title><content type="html">&lt;p&gt;I recently needed to setup IIS in Vista (again) to support my ASP.NET &amp;amp; WCF development purposes. Since there are a few different things to remember when setting up IIS in Vista to support development purposes (ASP.NET, WCF, Windows Authentication, etc.) I figured others might benefit from a quick How To.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Prerequisite:&lt;/strong&gt; Make sure the .NET 3.0+ framework is installed.&lt;/p&gt;  &lt;h2&gt;1. In Vista, go to Control Panel -&amp;gt; Programs and Features&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/schnieds/SO4q2yOxsCI/AAAAAAAAADM/9FyWvpI-lWk/s1600-h/VistaPrograms4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="586" alt="Vista Programs" src="http://lh6.ggpht.com/schnieds/SO4q4EBvPwI/AAAAAAAAADQ/dgHYGEvmuDw/VistaPrograms_thumb2.png?imgmax=800" width="773" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;2. Select the IIS Feature Checkbox&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/schnieds/SO4q4qvZtxI/AAAAAAAAADU/vKcdQYwb3yk/s1600-h/IISFeature4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="391" alt="IIS Feature" src="http://lh4.ggpht.com/schnieds/SO4q4wNOpMI/AAAAAAAAADY/MX9T1tKAIV8/IISFeature_thumb2.png?imgmax=800" width="445" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;3. Select the ASP.NET Application Feature&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/schnieds/SO4q5X_iNlI/AAAAAAAAADc/kIP-DGcKhGM/s1600-h/ASP.NETIISFeature4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="413" alt="ASP.NET IIS Feature" src="http://lh4.ggpht.com/schnieds/SO4q59wmLrI/AAAAAAAAADg/SfgvdwCKxQU/ASP.NETIISFeature_thumb2.png?imgmax=800" width="445" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h2&gt;4. Select Authentication Feature(s) You Need&lt;/h2&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/schnieds/SO4q6KxSrSI/AAAAAAAAADk/e7atA1RxBhg/s1600-h/IISSecurityFeatures4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="431" alt="IIS Security Features" src="http://lh3.ggpht.com/schnieds/SO4q6_KJrfI/AAAAAAAAADo/NeAbG1XRjFw/IISSecurityFeatures_thumb2.png?imgmax=800" width="445" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;h2&gt;5. Register WCF Handlers With IIS7&lt;/h2&gt;  &lt;p&gt;Run the following command from the command prompt to register the WCF handlers with IIS7:&lt;/p&gt;  &lt;p&gt;&amp;quot;%windir%\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe&amp;quot; -r -y&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/schnieds/SO4q78d0B0I/AAAAAAAAADs/1j7XYTpQ8jw/s1600-h/WCFHandlerInstaller4.png"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="356" alt="WCF Handler Installer" src="http://lh6.ggpht.com/schnieds/SO4q8Cc7oxI/AAAAAAAAADw/OaMVZ_ZO3_c/WCFHandlerInstaller_thumb2.png?imgmax=800" width="693" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;That's it, you should be good to go with your ASP.NET and/or WCF development needs under Vista.&lt;/p&gt;  &lt;h3&gt;Common Error Messages&lt;/h3&gt;  &lt;p&gt;If you don't have the ASP.NET feature installed, you will get the following error message... just FYI.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault=&amp;quot;Deny&amp;quot;), or set explicitly by a location tag with overrideMode=&amp;quot;Deny&amp;quot; or the legacy allowOverride=&amp;quot;false&amp;quot;.&lt;/strong&gt; &lt;/p&gt;  &lt;p&gt;------------------------------------------------------------------------------------------------------------------------------&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Server Error in Application &amp;#8220;DEFAULT WEB SITE/ EmployeeService &amp;#8220;Internet Information Services 7.0&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Error Summary&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;HTTP Error 404.3 - Not Found&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map. Detailed Error InformationModule StaticFileModule&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Aaron    &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt; &lt;br /&gt;&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f10%2fsetting-up-iis7-in-vista-for-aspnet-wcf.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f10%2fsetting-up-iis7-in-vista-for-aspnet-wcf.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/U_-1KKj8gcA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/7117326623930420582/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=7117326623930420582" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/7117326623930420582?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/7117326623930420582?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/U_-1KKj8gcA/setting-up-iis7-in-vista-for-aspnet-wcf.html" title="Setting Up IIS7 In Vista For ASP.NET / WCF Development Purposes" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh6.ggpht.com/schnieds/SO4q4EBvPwI/AAAAAAAAADQ/dgHYGEvmuDw/s72-c/VistaPrograms_thumb2.png?imgmax=800" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://www.schnieds.com/2008/10/setting-up-iis7-in-vista-for-aspnet-wcf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUEGRXo8eyp7ImA9WxRRGE0.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-6230795413840213508</id><published>2008-09-30T13:42:00.000-07:00</published><updated>2008-09-30T13:47:04.473-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-30T13:47:04.473-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>How To Have a Successful .NET Developer Interview</title><content type="html">&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f09%2fhow-to-have-successful-net-developer.html"&gt;&lt;img src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.schnieds.com%2f2008%2f09%2fhow-to-have-successful-net-developer.html" border="0" alt="kick it on DotNetKicks.com" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have been through a number of interviews now in my career and I have fared pretty well in many of them. While going through the interviews, I have created a mental list of what has worked well and what made a good impression on those conducting the interview. I have also made note of what impresses me (or turns me off) when I am the one conducting an interview.  &lt;br /&gt;&lt;br /&gt;Here are my top tips for success during your .NET developer interview.  &lt;br /&gt;&lt;br /&gt; &lt;h2&gt;Have an Honest Resume   &lt;br /&gt;&lt;/h2&gt; A successful interview starts with your resume. If you exaggerate or flat out lie about your experience and/or skills you are setting yourself up for failure. The truth is always the best policy when looking for a new job (and in life in general.) If you don't have the skills that the hiring company is looking for, then it isn't a good match. If they know your honest strengths &amp;amp; weaknesses before they hire you, there won't be a rude awakening when you start working and can't perform as expected.  &lt;br /&gt;&lt;br /&gt;If you look at your resume and realize that your skills aren't very attractive, then it is time to update your skills - not throw every tech buzzword you can think of into your resume.  &lt;br /&gt;&lt;br /&gt;On the flip side of this, don't under-value yourself on your resume either. Make sure to highlight what you are good at and confidently state your level of expertise in an area. If you are unsure of what level you are in an area, compare your skills to those of your co-workers &amp;amp; peers. This is usually a good way to determine your level of expertise in a given area.  &lt;br /&gt;&lt;br /&gt; &lt;h2&gt;Confidence&lt;/h2&gt; Easier said than done, but you need to go into an interview with confidence. If you followed my first point and have an honest resume, this part will come a lot easier.  &lt;br /&gt;&lt;br /&gt;If you doubt your abilities &amp;amp; what you can accomplish it will come across in the interview. If you need to, rehearse answers to common questions that you might face, talk through your past projects &amp;amp; experience aloud (it might seem strange, but it will help you become more comfortable) and make note of your strengths before entering the interview. The more preparation you do, the more comfortable you will be during the interview.  &lt;br /&gt;&lt;br /&gt;There is a fine line between being confident &amp;amp; being boastful, and you want to stay on the confident side. Don't go into the interview thinking that you are the biggest, baddest developer the company has ever seen - there will always be someone better out there. Valuable team players recognize their need for others on the team.  &lt;br /&gt;&lt;br /&gt; &lt;h2&gt;Living Examples of Your Work&lt;/h2&gt; If you want to set yourself apart from other candidates you need to show your prospective employer why they should hire you over Joe Schmoe #2. One way to do this is give your prospective employer the ability to view an example of your work first hand. Interviews are great, but nothing is as helpful as being able to review actual code that a potential employee has engineered.  &lt;br /&gt;&lt;br /&gt;If you are a website developer, figure out something that interests you and develop it in your free time. Create a fan site for your hobby, a site about your family or even develop your own application as a side business.  &lt;br /&gt;&lt;br /&gt;Create a blog. Whether or not you are a website developer, you can have a technical blog that showcases your interests, provides code samples &amp;amp; also demonstrates your communication skills &amp;amp; ability to document your work.  &lt;br /&gt;&lt;br /&gt; &lt;h2&gt;Preparation&lt;/h2&gt; Do your homework before you go to the interview. Read up about the company you are interviewing with, search professional social networking sites for information on the people interviewing you, prepare answers for technical questions as well as behavioral questions. If you go into the interview well prepared you will be more confident &amp;amp; comfortable in your answers and your prospective employer will notice the polish.  &lt;br /&gt;&lt;br /&gt; &lt;h2&gt;Ask Important Questions&lt;/h2&gt;  &lt;p&gt;  &lt;br /&gt;As part of your preparation, write down questions to ask your prospective employer. Figure out what makes you happy as a developer: Do you like chaotic programming? Are you more structured? Do you want engineering vs. get 'er done development? Do you care about having different environments to work in (Dev, Test, Prod)? Is a QA team important to you? Based on the working conditions that make you enjoy development, come up with a set of questions to ask your prospective employer to learn more about how they approach software development.&lt;/p&gt;  &lt;p&gt;Example questions:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;What size is the company? &lt;/li&gt;    &lt;li&gt;What size is the development team? &lt;/li&gt;    &lt;li&gt;Are there dedicated resources for server administration, database administration, QA, etc.? &lt;/li&gt;    &lt;li&gt;Are there training opportunities available? Are there funds available for off site training classes? &lt;/li&gt;    &lt;li&gt;Could you describe the process for an average project? (i.e. sales, marketing, deadlines, requirements, etc.) &lt;/li&gt;    &lt;li&gt;Are there any development best practices in place? &lt;/li&gt;    &lt;li&gt;Do you adhere to a specific SDLC?     &lt;br /&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h2&gt;Dress Like a Professional   &lt;br /&gt;&lt;/h2&gt; I know this is a big thing to ask for most computer geeks, but dress professionally. Early in my career one of the executives at a company I worked for told me this : "Dressing professionally is one of the easiest things you can do to make a big impact on how people view you." This has stuck with me and is something that I have followed throughout my career. You are applying for a professional level position and you should dress the part. This is an easy thing to do and it is just silly to give a bad first impression by looking like a slob during your interview.  &lt;br /&gt;&lt;br /&gt;Buy a nice suit &amp;amp; tie. If you can't coordinate colors to save your life, then find a cute girl working in the suit department at the store of your choice and have her select an appropriate business suit, tie &amp;amp; shirt. Comb your hair, shave &amp;amp; polish up your look.  &lt;br /&gt;&lt;br /&gt;After you get hired you can dress according to company policy for developers, but make a professional first impression.  &lt;br /&gt;&lt;br /&gt;Hope that helps!  &lt;br /&gt;&lt;br /&gt;Aaron  &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com/"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/wZ4NTsho9J8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/6230795413840213508/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=6230795413840213508" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6230795413840213508?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/6230795413840213508?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/wZ4NTsho9J8/how-to-have-successful-net-developer.html" title="How To Have a Successful .NET Developer Interview" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>6</thr:total><feedburner:origLink>http://www.schnieds.com/2008/09/how-to-have-successful-net-developer.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UCQ3gyfCp7ImA9WxRSEEo.&quot;"><id>tag:blogger.com,1999:blog-1328514867467683594.post-1218526584942630454</id><published>2008-09-09T23:17:00.000-07:00</published><updated>2008-09-10T13:41:02.694-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-10T13:41:02.694-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MySQL" /><category scheme="http://www.blogger.com/atom/ns#" term="SQL" /><title>Plesk MySQL Performance Settings</title><content type="html">&lt;p&gt;One of the servers I was working on recently had a Plesk control panel installed on it, which as it turns out can greatly effect MySQL performance. By default, the client database settings that Plesk uses for MySQL limit the resources allocated to your clients. This can be good or bad. If you are in the web hosting business and don't want your clients taking your server down with heavy MySQL usage this is probably a good thing. However, if you are running the server as a dedicated web application server and want all of the power you can get for your app, as I am, this is a bad thing.&lt;/p&gt;  &lt;p&gt;After a lot of tracing, I found that my web application was experiencing terrible MySQL performance. I did a bunch of research and found a MySQL configuration that solved all of my performance issues. The key to getting good MySQL performance on a Plesk controlled server is to tweak the client MySQL settings.&lt;/p&gt;  &lt;h3&gt;MySQL my.ini Performance Configuration&lt;/h3&gt;  &lt;p&gt;I found the following MySQL configuration settings solved all of my performance issues. (Make sure you edit the client configuration, see the next section for more on that.)&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;[MySQLD]     &lt;br /&gt;port=3306     &lt;br /&gt;basedir=C:\\Program Files\\SWsoft\\Plesk\\Databases\\MySQL     &lt;br /&gt;datadir=C:\\Program Files\\SWsoft\\Plesk\\Databases\\MySQL\\Data     &lt;br /&gt;default-character-set=latin1     &lt;br /&gt;default-storage-engine=INNODB     &lt;br /&gt;query_cache_size=64M     &lt;br /&gt;table_cache=1024     &lt;br /&gt;tmp_table_size=32M     &lt;br /&gt;thread_cache=32     &lt;br /&gt;myisam_max_sort_file_size=100G     &lt;br /&gt;myisam_max_extra_sort_file_size=100G     &lt;br /&gt;myisam_sort_buffer_size=2M     &lt;br /&gt;key_buffer_size=32M     &lt;br /&gt;read_buffer_size=16M     &lt;br /&gt;read_rnd_buffer_size=2M     &lt;br /&gt;sort_buffer_size=2M     &lt;br /&gt;innodb_additional_mem_pool_size=24M     &lt;br /&gt;innodb_flush_log_at_trx_commit=1     &lt;br /&gt;innodb_log_buffer_size=10M     &lt;br /&gt;innodb_buffer_pool_size=64M     &lt;br /&gt;innodb_log_file_size=10M     &lt;br /&gt;innodb_thread_concurrency=8     &lt;br /&gt;max_connections=300     &lt;br /&gt;key_buffer=48M     &lt;br /&gt;max_allowed_packet=5M     &lt;br /&gt;sort_buffer=2M     &lt;br /&gt;net_buffer_length=4K     &lt;br /&gt;old_passwords=1     &lt;br /&gt;[client]     &lt;br /&gt;port=3306&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;My Server Specs:&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Intel Dual Core @ 2GHz    &lt;br /&gt;2 GB of memory     &lt;br /&gt;(You may need to tweak the MySQL configuration settings I posted above if you server specs are drastically different than mine.)&lt;/p&gt;  &lt;h3&gt;Plesk MySQL Setting Locations&lt;/h3&gt;  &lt;p&gt;There are two different locations for MySQL settings in Plesk. One location contains a my.ini file that effects any client databases you create. The other location contains a my.ini file that effects Plesk's operation. &lt;em&gt;The important one to focus on here is the Client my.ini.      &lt;br /&gt;&lt;/em&gt;    &lt;br /&gt;&lt;strong&gt;Client MySQL Settings      &lt;br /&gt;&lt;/strong&gt;C:\Program Files\SWSoft\Plesk\Databases\MySQL\Data\my.ini     &lt;br /&gt;    &lt;br /&gt;&lt;strong&gt;Plesk MySQL Settings&lt;/strong&gt;     &lt;br /&gt;C:\Program Files\SWSoft\Plesk\MySQL\Data\my.ini     &lt;br /&gt;&lt;/p&gt;  &lt;p&gt;-Aaron    &lt;br /&gt;&lt;a href="http://www.churchofficeonline.com"&gt;http://www.churchofficeonline.com&lt;/a&gt;&lt;/p&gt;  &lt;img src="http://feeds.feedburner.com/~r/schnieds/RXSk/~4/zr6QS_64qTc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.schnieds.com/feeds/1218526584942630454/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=1328514867467683594&amp;postID=1218526584942630454" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/1218526584942630454?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1328514867467683594/posts/default/1218526584942630454?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/schnieds/RXSk/~3/zr6QS_64qTc/plesk-mysql-performance-settings.html" title="Plesk MySQL Performance Settings" /><author><name>Aaron Schnieder</name><uri>http://www.blogger.com/profile/13203827771563617211</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.schnieds.com/2008/09/plesk-mysql-performance-settings.html</feedburner:origLink></entry></feed>
