<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Scott's Blog</title><link>http://weblogs.asp.net/srkirkland/default.aspx</link><description>Sharing tales of [Alt].NET development</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>CI Deployment Of Azure Web Roles Using TeamCity</title><link>http://weblogs.asp.net/srkirkland/archive/2012/09/11/ci-deployment-of-azure-web-roles-using-teamcity.aspx</link><pubDate>Tue, 11 Sep 2012 15:47:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8910151</guid><dc:creator>srkirkland</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=8910151</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2012/09/11/ci-deployment-of-azure-web-roles-using-teamcity.aspx#comments</comments><description>&lt;p&gt;After recently migrating an important new website to use Windows Azure “Web Roles” I wanted an easier way to deploy new versions to the Azure Staging environment as well as a reliable process to rollback deployments to a certain “known good” source control commit checkpoint.&amp;#160; By configuring our JetBrains’ TeamCity CI server to utilize Windows Azure PowerShell cmdlets to create new automated deployments, I’ll show you how to take control of your Azure publish process.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Step 0: Configuring your Azure Project in Visual Studio&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Before we can start looking at automating the deployment, we should make sure manual deployments from Visual Studio are working properly.&amp;#160; Detailed information for setting up deployments can be found at &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/ff683672.aspx#PublishAzure"&gt;http://msdn.microsoft.com/en-us/library/windowsazure/ff683672.aspx#PublishAzure&lt;/a&gt; or by doing some quick Googling, but the basics are as follows:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Install the prerequisite Windows Azure SDK &lt;/li&gt;    &lt;li&gt;Create an Azure project by right-clicking on your web project and choosing “Add Windows Azure Cloud Service Project” (or by manually adding that project type) &lt;/li&gt;    &lt;li&gt;Configure your Role and Service Configuration/Definition as desired &lt;/li&gt;    &lt;li&gt;Right-click on your azure project and choose “Publish,” create a publish profile, and push to your web role &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;You don’t actually have to do step #4 and create a publish profile, but it’s a good exercise to make sure everything is working properly.&amp;#160; Once your Windows Azure project is setup correctly, we are ready to move on to understanding the Azure Publish process.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Understanding the Azure Publish Process&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;The actual Windows Azure project is fairly simple at its core—it builds your dependent roles (in our case, a web role) against a specific service and build configuration, and outputs two files:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;strong&gt;ServiceConfiguration.Cloud.cscfg&lt;/strong&gt;: This is just the file containing your package configuration info, for example Instance Count, OsFamily, ConnectionString and other Setting information. &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;ProjectName.Azure.cspkg&lt;/strong&gt;: This is the package file that contains the guts of your deployment, including all deployable files. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;When you package your Azure project, these two files will be created within the directory ./[ProjectName].Azure/bin/[ConfigName]/app.publish/.&amp;#160; If you want to build your Azure Project from the command line, it’s as simple as calling MSBuild on the “Publish” target:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;msbuild.exe /target:Publish&lt;/p&gt; &lt;/blockquote&gt;  &lt;h3&gt;&lt;u&gt;Windows Azure PowerShell Cmdlets&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;The last pieces of the puzzle that make CI automation possible are the Azure PowerShell Cmdlets (&lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj156055.aspx"&gt;http://msdn.microsoft.com/en-us/library/windowsazure/jj156055.aspx&lt;/a&gt;).&amp;#160; These cmdlets are what will let us create deployments without Visual Studio or other user intervention.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Preparing TeamCity for Azure Deployments&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Now we are ready to get our TeamCity server setup so it can build and deploy Windows Azure projects, which we now know requires the Azure SDK and the Windows Azure PowerShell Cmdlets.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Installing the Azure SDK is easy enough, just go to &lt;a href="https://www.windowsazure.com/en-us/develop/net/"&gt;https://www.windowsazure.com/en-us/develop/net/&lt;/a&gt; and click “Install” &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;Once this SDK is installed, I recommend running a test build to make sure your project is building correctly.&amp;#160; You’ll want to setup your build step using MSBuild with the “Publish” target against your solution file.&amp;#160; Mine looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_4179311D.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1C7B70A4.png" width="716" height="524" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Assuming the build was successful, you will now have the two *.cspkg and *cscfg files within your build directory.&amp;#160; If the build was red (failed), take a look at the build logs and keep an eye out for “unsupported project type” or other build errors, which will need to be addressed before the CI deployment can be completed.&lt;/p&gt;  &lt;p&gt;With a successful build we are now ready to install and configure the Windows Azure PowerShell Cmdlets:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Follow the instructions at &lt;a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj554332"&gt;http://msdn.microsoft.com/en-us/library/windowsazure/jj554332&lt;/a&gt; to install the Cmdlets and configure PowerShell &lt;/li&gt;    &lt;li&gt;After installing the Cmdlets, you’ll need to get your Azure Subscription Info using the &lt;strong&gt;Get-AzurePublishSettingsFile&lt;/strong&gt; command. Store the resulting *.publishsettings file somewhere you can get to easily, like C:\TeamCity, because you will need to reference it later from your deploy script. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;u&gt;Scripting the CI Deploy Process&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Now that the cmdlets are installed on our TeamCity server, we are ready to script the actual deployment using a TeamCity “PowerShell” build runner.&amp;#160; Before we look at any code, here’s a breakdown of our deployment algorithm:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Setup your variables, including the location of the *.cspkg and *cscfg files produced in the earlier MSBuild step (remember, the folder is something like [ProjectName].Azure/bin/[ConfigName]/app.publish/ &lt;/li&gt;    &lt;li&gt;Import the Windows Azure PowerShell Cmdlets &lt;/li&gt;    &lt;li&gt;Import and set your Azure Subscription information (this is basically your authentication/authorization step, so protect your settings file &lt;/li&gt;    &lt;li&gt;Now look for a current deployment, and if you find one Upgrade it, else Create a new deployment &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Pretty simple and straightforward.&amp;#160; Now let’s look at the code (also available as a gist here: &lt;a href="https://gist.github.com/3694398"&gt;https://gist.github.com/3694398&lt;/a&gt;):&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;     &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;$subscription = &lt;span style="color: #006080"&gt;&amp;quot;[Your Subscription Name]&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;$service = &lt;span style="color: #006080"&gt;&amp;quot;[Your Azure Service Name]&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;$slot = &lt;span style="color: #006080"&gt;&amp;quot;staging&amp;quot;&lt;/span&gt; &lt;span style="color: #008000"&gt;#staging or production&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;$package = &lt;span style="color: #006080"&gt;&amp;quot;[ProjectName]\bin\[BuildConfigName]\app.publish\[ProjectName].cspkg&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;$configuration = &lt;span style="color: #006080"&gt;&amp;quot;[ProjectName]\bin\[BuildConfigName]\app.publish\ServiceConfiguration.Cloud.cscfg&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;$timeStampFormat = &lt;span style="color: #006080"&gt;&amp;quot;g&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;$deploymentLabel = &lt;span style="color: #006080"&gt;&amp;quot;ContinuousDeploy to $service v%build.number%&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;Write-Output &lt;span style="color: #006080"&gt;&amp;quot;Running Azure Imports&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;Import-Module &lt;span style="color: #006080"&gt;&amp;quot;C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\Azure\*.psd1&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;Import-AzurePublishSettingsFile &lt;span style="color: #006080"&gt;&amp;quot;C:\TeamCity\[PSFileName].publishsettings&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;Set-AzureSubscription -CurrentStorageAccount $service -SubscriptionName $subscription&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; Publish(){&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; $deployment = Get-AzureDeployment -ServiceName $service -Slot $slot -ErrorVariable a -ErrorAction silentlycontinue &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ($a[0] &lt;span style="color: #cc6633"&gt;-ne&lt;/span&gt; $null) {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - No deployment is detected. Creating a new deployment. &amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ($deployment.Name &lt;span style="color: #cc6633"&gt;-ne&lt;/span&gt; $null) {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    &lt;span style="color: #008000"&gt;#Update deployment inplace (usually faster, cheaper, won't destroy VIP)&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - Deployment exists in $servicename.  Upgrading deployment.&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    UpgradeDeployment&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; } &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    CreateNewDeployment&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; CreateNewDeployment()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    write-progress -id 3 -activity &lt;span style="color: #006080"&gt;&amp;quot;Creating New Deployment&amp;quot;&lt;/span&gt; -Status &lt;span style="color: #006080"&gt;&amp;quot;In progress&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - Creating New Deployment: In progress&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    $opstat = New-AzureDeployment -Slot $slot -Package $package -Configuration $configuration -label $deploymentLabel -ServiceName $service&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    $completeDeploymentID = $completeDeployment.deploymentid&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    write-progress -id 3 -activity &lt;span style="color: #006080"&gt;&amp;quot;Creating New Deployment&amp;quot;&lt;/span&gt; -completed -Status &lt;span style="color: #006080"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - Creating New Deployment: Complete, Deployment ID: $completeDeploymentID&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&lt;span style="color: #0000ff"&gt;function&lt;/span&gt; UpgradeDeployment()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    write-progress -id 3 -activity &lt;span style="color: #006080"&gt;&amp;quot;Upgrading Deployment&amp;quot;&lt;/span&gt; -Status &lt;span style="color: #006080"&gt;&amp;quot;In progress&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - Upgrading Deployment: In progress&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    &lt;span style="color: #008000"&gt;# perform Update-Deployment&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    $setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $package -Configuration $configuration -label $deploymentLabel -ServiceName $service -Force&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    $completeDeployment = Get-AzureDeployment -ServiceName $service -Slot $slot&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    $completeDeploymentID = $completeDeployment.deploymentid&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;    write-progress -id 3 -activity &lt;span style="color: #006080"&gt;&amp;quot;Upgrading Deployment&amp;quot;&lt;/span&gt; -completed -Status &lt;span style="color: #006080"&gt;&amp;quot;Complete&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;    Write-Output &lt;span style="color: #006080"&gt;&amp;quot;$(Get-Date -f $timeStampFormat) - Upgrading Deployment: Complete, Deployment ID: $completeDeploymentID&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"&gt;Write-Output &lt;span style="color: #006080"&gt;&amp;quot;Create Azure Deployment&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"&gt;Publish&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Creating the TeamCity Build Step&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;The only thing left is to create a second build step, after your MSBuild “Publish” step, with the build runner type “PowerShell”.&amp;#160; Then set your script to “&lt;strong&gt;Source Code,&lt;/strong&gt;” the script execution mode to “&lt;strong&gt;Put script into PowerShell stdin with “-Command” arguments&lt;/strong&gt;” and then copy/paste in the above script (replacing the placeholder sections with your values).&amp;#160; This should look like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_50AF99EA.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_79BA38E6.png" width="713" height="637" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Wrap Up&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;After combining the &lt;strong&gt;MSBuild /target:Publish&lt;/strong&gt; &lt;strong&gt;step&lt;/strong&gt; (which creates the necessary Windows Azure *.cspkg and *.cscfg files) and a &lt;strong&gt;PowerShell script step &lt;/strong&gt;which utilizes the Azure PowerShell Cmdlets, we have a fully deployable build configuration in TeamCity.&amp;#160; You can configure this step to run whenever you’d like using build triggers – for example, you could even deploy whenever a new master branch deploy comes in and passes all required tests.&lt;/p&gt;

&lt;p&gt;In the script I’ve hardcoded that every deployment goes to the Staging environment on Azure, but you could deploy straight to Production if you want to, or even setup a deployment configuration variable and set it as desired.&lt;/p&gt;

&lt;p&gt;After your TeamCity Build Configuration is complete, you’ll see something that looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_42DFE4A0.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_2258A4EE.png" width="1005" height="91" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whenever you click the “Run” button, all of your code will be compiled, published, and deployed to Windows Azure!&lt;/p&gt;

&lt;p&gt;One additional enormous benefit of automating the process this way is that you can easily deploy any specific source control changeset by clicking the little ellipsis button next to &amp;quot;Run.”&amp;#160; This will bring up a dialog like the one below, where you can select the last change to use for your deployment.&amp;#160; Since Azure Web Role deployments don’t have any rollback functionality, this is a critical feature.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2FBEB7F4.png"&gt;&lt;img title="image" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_58C956F0.png" width="724" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8910151" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Tips/default.aspx">Tips</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MSBuild/default.aspx">MSBuild</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Git/default.aspx">Git</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Azure/default.aspx">Azure</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Cloud/default.aspx">Cloud</category></item><item><title>Git Deployment To An Azure WebSite: Keeping Configuration Secrets</title><link>http://weblogs.asp.net/srkirkland/archive/2012/08/08/git-deployment-to-an-azure-website-keeping-configuration-secrets.aspx</link><pubDate>Wed, 08 Aug 2012 19:01:15 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8825779</guid><dc:creator>srkirkland</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=8825779</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2012/08/08/git-deployment-to-an-azure-website-keeping-configuration-secrets.aspx#comments</comments><description>&lt;p&gt;Windows Azure &lt;a href="http://weblogs.asp.net/scottgu/archive/2012/06/07/meet-the-new-windows-azure.aspx" target="_blank"&gt;recently introduced their “Websites” concept&lt;/a&gt; which allows quick and easy deployment of ASPNET, Node.js and PHP web-sites to the Azure cloud.&amp;#160; One of the most exciting developments was the ability to deploy to web-sites rapidly using “&lt;a href="https://www.windowsazure.com/en-us/develop/net/common-tasks/publishing-with-git/" target="_blank"&gt;Git Publishing&lt;/a&gt;,” meaning if you are using Git you just need to add a new remote and do “git push azure” to deploy your code on demand.&lt;/p&gt;  &lt;p&gt;As I began to utilize this feature I stumbled quickly upon a problem – how do we configure web.config “secrets,” like app settings and connection string passwords?&amp;#160; Since git publishing just pushes your current repository directly to Azure, I was worried that I would have to check my secrets into source control, which is an obviously undesirable solution, especially on collaborative teams.&lt;/p&gt;  &lt;p&gt;It turns out there are a few aspects of Azure which allow you to keep configuration secrets and still deploy your web-site using the awesome git publishing method.&amp;#160; In this blog post I’m going to show you how easy it is to configure appSettings, and I’ll show you a workaround for keeping your connectionStrings and other information secret as well.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;AppSettings are easy!&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Configuring AppSettings are very simple thanks to the Windows Azure “Portal” (&lt;a href="http://windows.azure.com"&gt;http://windows.azure.com&lt;/a&gt;).&amp;#160; All you have to do is go into the Dashboard for your web-site and click &amp;quot;Configure.”&amp;#160; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_25763482.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_398F510B.png" width="611" height="141" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Now scroll down and you will see a section for app settings and connection strings.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_0AC99869.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_50DA557C.png" width="862" height="382" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Any app setting key-value pair you set here will either overwrite an existing value in your web.config or add a new value if there is no match.&amp;#160; This is the expected behavior, and it makes it very easy to setup your configuration from the web portal.&amp;#160; &lt;/p&gt;  &lt;p&gt;The app settings here will persist across deployments, so you can keep your local web.config checked into source control and free of secret configuration info.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;ConnectionStrings Cannot Be Modified&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Unfortunately, as you can see in the above picture, connection strings cannot be set through the admin interface.&amp;#160; Every time we deploy, the values in your web.config (possibly merged with your transformation file) will be used.&amp;#160; At this point it doesn’t seem like we can store connection string information outside of source control, however, with a little knowledge of the deployment process, you will see this is not an insurmountable issue.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;The Git Publishing Process&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;The engine behind the git deployment process in Windows Azure is a project called &lt;a href="https://github.com/projectkudu/kudu" target="_blank"&gt;“Kudu,” which is an open source project hosted on GitHub&lt;/a&gt;.&amp;#160; The relevant details we need to know about Kudu are:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Currently Kudu will run the build configuration “Release” for any deployment&lt;/li&gt;    &lt;li&gt;Kudu will NOT remove a file if there is no matching file in your deployment&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Point #2 here is the key—if you have a file sitting on the server, let’s say “robots.txt,” and then you remove that file from your git repository and deploy using your latest change, that robots.txt file will still exist on the remote.&lt;/p&gt;  &lt;p&gt;With this in mind, and knowing that Kudu uses the “Release” build configuration, let’s try to keep our secret information outside of source control and attempt a deployment.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;ConnectionStrings and Other Web.Config Transformations&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;First we have to make sure web.release.config is not part of our repository.&amp;#160; Add web.release.config to your .gitignore file and, if necessary, use “git rm” to remove the file from your repository.&amp;#160; Now that web.release.config will not be sent up as part of our deployment, we just have to figure out how to get our secret web.release.config file onto the server, knowing that Kudu will not replace the file.&lt;/p&gt;  &lt;p&gt;Here our old friend FTP comes to the rescue. Under your website in the Azure portal, go to “Dashboard” and down the right side you will see some basic information about your setup, including “FTP HOSTNAME.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_5001EF92.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_682559ED.png" width="288" height="383" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We are going to use that FTP site to drop in our desired web.release.config file, and when we do future deployments it will be used to transform our base web.config with whatever magical values we chose.&lt;/p&gt;  &lt;p&gt;I’m just going to use windows explorer for FTP to keep things simple.&amp;#160; On connecting you get the following prompt:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_7C3E7676.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_3B2FF712.png" width="496" height="353" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Make sure to enter your username with the dashboard’s “DEPLOYMENT USER” text, which is ‘{sitename}\{username}.’&lt;/p&gt;  &lt;p&gt;Once you are in, you’ll see two folders, “Log Files” and “site.” You’ll want to choose “site” and then “repository” so the full path is “&lt;a title="ftp://waws-prod-blu-001.ftp.azurewebsites.windows.net/site/repository/" href="ftp://[yourftp].ftp.azurewebsites.windows.net/site/repository/"&gt;ftp://[yourftp].ftp.azurewebsites.windows.net/site/repository/&lt;/a&gt;&amp;quot;&lt;/p&gt;  &lt;p&gt;Within this folder, navigate to your web.config location and drop in your web.release.config file.&amp;#160; This file will persist across deployments and automatically transform your web.config.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_6BE2FEBD.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1C960669.png" width="978" height="287" /&gt;&lt;/a&gt;&lt;/p&gt;      &lt;p&gt;As you can see above, towards the middle of this deployment Kudu reported to us “Transformed Web.config using Web.Release.confg.” This is exactly what we were trying to accomplish, and now we have the ability to put anything we want into our Web.Release.config, keep that information outside of source control, and have the transformations persist across deployments.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Conclusion&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;It is very simple to configure “AppSettings” using the Azure Portal, but setting other web.config values require a bit more effort, especially when you don’t want your configuration values to be stored and versioned in source control.&amp;#160; Using FTP, we’ve shown that we can directly place our configuration transform file and have it automatically merge on deployment, allowing us to set virtual any option we desire.&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8825779" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Source+Control/default.aspx">Source Control</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Git/default.aspx">Git</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Azure/default.aspx">Azure</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Cloud/default.aspx">Cloud</category></item><item><title>Git Aliases</title><link>http://weblogs.asp.net/srkirkland/archive/2012/05/17/git-aliases.aspx</link><pubDate>Thu, 17 May 2012 17:18:39 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8493783</guid><dc:creator>srkirkland</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=8493783</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2012/05/17/git-aliases.aspx#comments</comments><description>&lt;p&gt;Many git users may not be aware that you can setup git aliases for either providing shortcuts to existing commands (like typing ‘git co’ instead of ‘git checkout’) or even for creating entirely new commands (‘git hist’ for printing your git history formatted how you like it).&amp;#160; Git aliases can be local to a single repository, or (more commonly) global.&lt;/p&gt;  &lt;p&gt;To manage git aliases you need to use the ‘git config’ command (see &lt;a href="http://git-scm.com/docs/git-config"&gt;http://git-scm.com/docs/git-config&lt;/a&gt;), and for making your aliases global use ‘git config –global’.&amp;#160; Let’s make a quick alias now:&lt;/p&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: &amp;#39;Courier New&amp;#39;, 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;git config --&lt;span style="color: #0000ff"&gt;global&lt;/span&gt; alias.co &lt;span style="color: #006080"&gt;'checkout'&lt;/span&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This command tells git to create a global alias ‘&lt;strong&gt;co&lt;/strong&gt;’ which will fire off the ‘checkout’ command when typed.&amp;#160; This saves a few keystrokes, so now ‘git co master’ does a checkout of master, or ‘git co mybranch’ will checkout the branch ‘mybranch’.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;My Favorite Aliases&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Here’s a list of my favorite aliases that I make sure to add to any new git install.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, 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;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --&lt;span style="color: #0000ff"&gt;global&lt;/span&gt; alias.go &lt;span style="color: #006080"&gt;'checkout'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --&lt;span style="color: #0000ff"&gt;global&lt;/span&gt; alias.&lt;span style="color: #0000ff"&gt;in&lt;/span&gt; &lt;span style="color: #006080"&gt;'commit -a'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --&lt;span style="color: #0000ff"&gt;global&lt;/span&gt; alias.up &lt;span style="color: #006080"&gt;'push origin'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --&lt;span style="color: #0000ff"&gt;global&lt;/span&gt; alias.down &lt;span style="color: #006080"&gt;'pull origin'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I particularly like these aliases since they reduce typing on the most common commands, but also because they make me feel just a little bit like James Brown singing:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;uh uh &lt;strong&gt;&lt;em&gt;git down&lt;/em&gt;&lt;/strong&gt;! &lt;em&gt;&lt;strong&gt;git in&lt;/strong&gt;&lt;/em&gt;!&amp;#160; huh, yea.&amp;#160; &lt;strong&gt;&lt;em&gt;git up&lt;/em&gt;&lt;/strong&gt;!&amp;#160; ooohhh owwwww, &lt;em&gt;&lt;strong&gt;git in&lt;/strong&gt;&lt;/em&gt; now, yea &lt;strong&gt;&lt;em&gt;git up&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Delusional rock fantasy aside, the above is actually a regular git flow I&amp;#160; use every day, using the above aliases to pull down the latest, check in changes, then push back up to origin.&lt;/p&gt;

&lt;p&gt;&lt;img style="display: inline" src="http://upload.wikimedia.org/wikipedia/commons/7/70/Jamesbrown3-2.jpg" /&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Other Useful Aliases&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Here’s a couple of other useful aliases to save you some finger and brain strain:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, 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;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --global alias.st &lt;span style="color: #006080"&gt;'status'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --global alias.br &lt;span style="color: #006080"&gt;'checkout -b'&lt;/span&gt; &lt;span style="color: #008000"&gt;//For creating branches&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --global alias.a &lt;span style="color: #006080"&gt;'add .'&lt;/span&gt; &lt;span style="color: #008000"&gt;//Shortcut to add all changes to the index&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --global alias.hist = &lt;span style="color: #006080"&gt;'log --pretty --graph --date=short'&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can get pretty complex with aliases, having them call out to shell scripts or running multiple commands, but I’ll stick with the basics here &amp;amp; point you at some advanced usage examples on other pages at the end of this post.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Viewing Your Stored Aliases&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Your aliases are stored in two places: global aliases are stored in ~/.gitconfig (.gitconfig in your home directory) , and local aliases are stored in .git/config (the config file within your local git directory).&amp;#160; However, you don’t need to ever look in those files—instead use one of the two the following commands:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, 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;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --get-regex alias &lt;span style="color: #008000"&gt;//Shows all of your aliases&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;git config --global --get-regex alias //Just global aliases&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now that you have a list of your aliases, you can add more or remove/replace using ‘git config’ (for example, to remove alias.test, use ‘git config –unset alias.test’)&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Conclusion and Links&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Git aliases can save you lots of typing and can prevent dangerous typos of difficult commands (for example, you could alias rebases or fetch/merge).&amp;#160; They are incredibly flexible, powerful, and easy to setup (and, since they live in your .gitconfig, quite portable).&amp;#160; &lt;/p&gt;

&lt;p&gt;I’ll leave you with some links to useful git alias information:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://git-scm.com/docs/git-config" target="_blank"&gt;Git config man page&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="https://git.wiki.kernel.org/index.php/Aliases" target="_blank"&gt;Git wiki alias page on kernel.org—useful, detailed and complex examples&lt;/a&gt;&lt;/li&gt;

  &lt;li&gt;&lt;a href="http://superuser.com/questions/169695/what-are-your-favorite-git-aliases" target="_blank"&gt;StackExchange post on favorite git aliases (including one that goes to the ‘Danger Zone’)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8493783" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Tips/default.aspx">Tips</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Source+Control/default.aspx">Source Control</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Git/default.aspx">Git</category></item><item><title>CI Deployments To IIS VIA MS Web Deploy 2.0</title><link>http://weblogs.asp.net/srkirkland/archive/2012/05/14/ci-deployments-to-iis-via-ms-web-deploy-2-0.aspx</link><pubDate>Mon, 14 May 2012 18:15:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:8462339</guid><dc:creator>srkirkland</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=8462339</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2012/05/14/ci-deployments-to-iis-via-ms-web-deploy-2-0.aspx#comments</comments><description>&lt;p&gt;&lt;font size="2"&gt;Now that I have my source code being checked into &lt;/font&gt;&lt;a href="https://github.com/" target="_blank"&gt;&lt;font size="2"&gt;GitHub&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; and have &lt;/font&gt;&lt;a href="http://www.jetbrains.com/teamcity/" target="_blank"&gt;&lt;font size="2"&gt;TeamCity&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; doing automatic builds (and running tests), I thought it was about time to take the last big step &lt;/font&gt;&lt;font size="2"&gt;and automatically deploy the latest version of an application to a live site (either for testing or just straight to production, it’s up to you) whenever a successful build has taken place.&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font size="2"&gt;The best resource I’ve found for deploying directly from TeamCity (note: the steps would be the same for any CI server) can be found in Troy Hunt’s excellent 5 part blog series here: &lt;a href="http://www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity.html"&gt;http://www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity.html&lt;/a&gt;.&amp;#160; It is very comprehensive and well worth a read, but I had some issues configuring deployment permissions and wanted to detail them here in case it helps someone else down the road.&lt;/font&gt;&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;An Overview Of the CI Deployment Process&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;Here’s a basic idea of how to get started—if you’ve ever used the Visual Studio 2010 “Publish” wizard then you are 1/2 way there.&amp;#160; If you have any questions on these steps, refer to &lt;/font&gt;&lt;a href="http://www.troyhunt.com/2010/11/you-deploying-it-wrong-teamcity.html" target="_blank"&gt;&lt;font size="2"&gt;the blog series mentioned above&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; or Google with Bing for help.&lt;/font&gt;&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;font size="2"&gt;Install Microsoft Web Deploy 2.0 from &lt;/font&gt;&lt;a href="http://www.iis.net/download/webdeploy"&gt;&lt;font size="2"&gt;http://www.iis.net/download/webdeploy&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt; on the server you wish to publish to.&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Setup Web.Config transformations for your desired build configurations (see &lt;/font&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd465318.aspx"&gt;&lt;font size="2"&gt;http://msdn.microsoft.com/en-us/library/dd465318.aspx&lt;/font&gt;&lt;/a&gt;&lt;font size="2"&gt;)&lt;/font&gt; &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Inside Visual Studio, right click –&amp;gt; properties on your Web project, and under Package/Publish Web setup the IIS Web Application name to match your IIS server&lt;/font&gt;       &lt;ul&gt;       &lt;li&gt;&lt;font size="2"&gt;This is the virtual directory inside IIS that your deployment will be pushed to.&amp;#160; Set it up for each desired build configuration.&lt;/font&gt; &lt;/li&gt;     &lt;/ul&gt;   &lt;/li&gt;    &lt;li&gt;Setup Permissions on your IIS Server to allow web deployment from your CI agent or service account (detailed below). &lt;/li&gt;    &lt;li&gt;&lt;font size="2"&gt;Craft an MSBuild command that will build AND deploy your web application, and run it during your CI Server build process (also detailed below).&lt;/font&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;&lt;u&gt;Deploying Via MSBuild&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;&lt;font size="2"&gt;That last point requires a bit of explanation as it’s the crux of the problem (other than permissions, which I’ll get to later).&amp;#160; What we want MSBuild to do here is to build your project/solution using the desired build configuration (like Debug/Release) and then to use the MS Web Deploy service to push your auto-created deployment package to IIS.&amp;#160; Here’s an example of MSBuild parameters from Troy’s blog that will accomplish this:&lt;/font&gt;&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, 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;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:Configuration=%env.Configuration%&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:DeployOnBuild=True&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:DeployTarget=MSDeployPublish&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:MsDeployServiceUrl=https://%env.TargetServer%/MsDeploy.axd&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:AllowUntrustedCertificate=True&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:MSDeployPublishMethod=WMSvc&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:CreatePackageOnPublish=True&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:UserName=AutoDeploy\Administrator&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:Password=Passw0rd&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="2"&gt;&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;Basically the above parameters use the provided env.Configuration (Debug/Release) to set the build configuration and then tell MSBulid to deploy using WMSvc (web management service) to the service url located at env.TargetServer (you can set the defaults on your CI server).&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;This is pretty handy, but I unfortunately for me (and maybe for you) there are two problems here:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;#1: The user (AutoDeploy\Administrator) needs to be an admin on your IIS, and you need to have allowed Administrators to bypass rules in the “Management Service Delegation” area of IIS (see ScottGu’s post here: &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/09/13/automating-deployment-with-microsoft-web-deploy.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/09/13/automating-deployment-with-microsoft-web-deploy.aspx&lt;/a&gt;).&amp;#160; For me, this is too much by itself.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;#2: The username and password as passed in plain text through your configuration, as shown above. &lt;a href="http://www.nooooooooooooooo.com/" target="_blank"&gt;Not good&lt;/a&gt;.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;The rest of this post will detail how to solve these issues, and in the end we will setup an service account that has non-admin access and which doesn’t require passing credentials manually.&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Setting Up the Service Account&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;The first step is to create a non-admin service account that will be used on both your build server and IIS boxes. I’ll be using a no-login domain account called “mydomain\builderservice”, but any account would work.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;On your CI server (in my case, TeamCity), you’ll want to run your build agent as your new service account, as shown here:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_079E16CD.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://weblogs.asp.net/blogs/srkirkland/image_thumb_1497F6DE.png" width="640" height="245" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;Note you might also have to give this service access to certain files. For example, in TeamCity the build agent needs access to C:\TeamCity\buildAgent to do its work.&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Changing the MSBuild Script to Run As “Current User”&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;This part was fairly tricky since simply removing the UserName/Password parameters from the msbuild command will not work as expected.&amp;#160; Instead you must specify the AuthType to be NTLM (or it will default to Basic) and the UserName=[blank] so it will impersonate the current user.&amp;#160; The relevant parameters are /P:UserName= /P:AuthType=NTLM.&amp;#160; This makes the final MSBuild parameters:&lt;/font&gt;&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, 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;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:Configuration=%env.Configuration%&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:DeployOnBuild=True &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:DeployTarget=MSDeployPublish &lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:MsDeployServiceUrl=https://%env.TargetServer%/MsDeploy.axd&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:AllowUntrustedCertificate=True &lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:MsDeployPublishMethod=WMSvc &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:CreatePackageOnPublish=True &lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:UserName= &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;/P:AuthType=NTLM&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;font size="2"&gt;Now that we have TeamCity running MSBuild with these parameters while running under a service account, we need to grant permission on the IIS server that has MS Deploy installed (%env.TargetServer%).&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;IIS Server Permission For Deployment&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;Your mileage may vary, but in order to get a successful web deployment from a non-administrator account, I had to perform the following steps, each of which I will explain in detail.&lt;/font&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;font size="2"&gt;Enable Windows Authentication for the Web Management Server (WMSvc)&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="2"&gt;Grant Management Service Delegation rights at the Site level to the necessary providers&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="2"&gt;Grant IIS Manager Permissions to your virtual application&lt;/font&gt; &lt;/li&gt;

  &lt;li&gt;&lt;font size="2"&gt;Grant file/folder permissions to the web directory&lt;/font&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;#1: &lt;font size="2"&gt;Enable Windows Authentication for the Web Management Server (WMSvc)&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;In order to get the WMSvc to accept my build agent credentials, I had to enable Windows Authentication inside the IIS Management Service. You can do this either from the UI or Windows Registry as described in &lt;a href="http://stackoverflow.com/a/4834248" target="_blank"&gt;this stackoverflow post&lt;/a&gt;.&amp;#160; For convenience, here is the regex key (make sure to restart the WMSvc after making the change): ‘reg add HKLM\Software\Microsoft\WebManagement\Server /v WindowsAuthenticationEnabled /t REG_DWORD /d 1’&lt;/font&gt;&lt;/p&gt;

&lt;h3&gt;#2: &lt;font size="2"&gt;Grant Management Service Delegation rights at the Site level to the necessary providers&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;Next you must Delegate to your service account the rights to perform certain actions through the management service providers. If you forget any of these you will get a helpful error message saying that you don’t have rights to run a certain provider (ex: “createApp”) so you’d then need to come back in and add those.&amp;#160; I needed the following providers: “contentPath, iisApp, createApp, setAcl.”&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;To set a delegation rule go to your site root in IIS and under Management choose “Management Service Delegation.”&amp;#160; Now choose “Add Rule” in the upper-right and choose the “Deploy Applications with Content” template (this has the best defaults) and then add in your desired providers. Mine looked like this:&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_6090061F.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://weblogs.asp.net/blogs/srkirkland/image_thumb_70BBCE18.png" width="345" height="532" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;font size="2"&gt;Click ok, and now that the rule is defined you just have to select the newly created rule and choose “Add User To Role.”&amp;#160; In the ensuing dialog enter the name of your service account and press OK.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_0B87F425.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://weblogs.asp.net/blogs/srkirkland/image_thumb_63E177FA.png" width="235" height="202" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;#3: &lt;font size="2"&gt;Grant IIS Manager Permissions to your virtual application&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;Now that you granted site-level provider access within the {userScope} path, you must give the account IIS permission on the site/application that you will be deploying to.&amp;#160; Choose your site and then under Management choose “IIS Manager Permissions.”&amp;#160; Now click “Allow User” and enter the account name again to grant access.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_3BCEC8DB.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://weblogs.asp.net/blogs/srkirkland/image_thumb_41A96C74.png" width="373" height="216" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;#4: &lt;font size="2"&gt;Grant file/folder permissions to the web directory&lt;/font&gt;&lt;/h3&gt;

&lt;p&gt;&lt;font size="2"&gt;This one is pretty obvious, but you still have to remember to give full control to your service account at the OS-folder level (ex: C:\inetpub\SiteName).&amp;#160; Right-click –&amp;gt; Properties –&amp;gt; Security –&amp;gt; Edit, and then choose Add.&amp;#160; Now type in your service account one more time, grant it full control, and you are finished.&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_1996BD55.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://weblogs.asp.net/blogs/srkirkland/image_thumb_26246A71.png" width="395" height="425" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Celebrate!&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;That was certainly a lot of info, and I hope it makes someone’s deployment configuration easier.&amp;#160; Integrating your build, test, and deployments with a CI Server like TeamCity has many advantages, including the ability to handle “deploy automatically only when all tests pass” and “oops, deploy the version from last week” scenarios.&lt;/p&gt;

&lt;p&gt;May all your Deployments be green.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_04C4C4D5.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://weblogs.asp.net/blogs/srkirkland/image_thumb_6847D2F4.png" width="241" height="71" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8462339" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MSBuild/default.aspx">MSBuild</category></item><item><title>Html5 Input Validation Presentation</title><link>http://weblogs.asp.net/srkirkland/archive/2011/06/21/html5-input-validation-presentation.aspx</link><pubDate>Tue, 21 Jun 2011 16:42:38 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7836949</guid><dc:creator>srkirkland</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7836949</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/06/21/html5-input-validation-presentation.aspx#comments</comments><description>&lt;p&gt;Last week I gave a presentations to the 2011 UC Davis IT Security Symposium that covered input validation features in HTML5.&amp;#160; I mostly discussed the following three topics:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;New Html5 Input Types (like &amp;lt;input type=”email” /&amp;gt;) &lt;/li&gt;    &lt;li&gt;Html5 Constraints (like &amp;lt;input type=”text” required maxlength=”8” /&amp;gt;) &lt;/li&gt;    &lt;li&gt;Polyfills &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;The slides only cover part of the story since there are a few “live demos.”&amp;#160; You can find all of the demo code on my github repository &lt;a href="https://github.com/srkirkland/ITSecuritySymposium"&gt;https://github.com/srkirkland/ITSecuritySymposium&lt;/a&gt;.&amp;#160; You’ll need ASP.NET Mvc 3 installed to run them.&lt;/p&gt;  &lt;p&gt;The slides are also available in my GitHub repository, but I’ve also added them to slideshare as well because that’s what the cool kids do: &lt;a href="http://www.slideshare.net/srkirkland/data-validation-in-web-applications"&gt;http://www.slideshare.net/srkirkland/data-validation-in-web-applications&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;I believe the presentation was well received and most people learned something, so I just wanted to share.&amp;#160; When loading up the Html5 demo just click on the Html5 tab and go through each example. Enjoy!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;[Examples from the Slides and Demos]&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_3F37E8CE.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_76F5F325.png" width="644" height="482" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_57A32685.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_67EE7871.png" width="643" height="484" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_153FE875.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_62AC6535.png" width="660" height="476" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7836949" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Html5/default.aspx">Html5</category></item><item><title>Deploy NuGet Packages During CI Build with TeamCity</title><link>http://weblogs.asp.net/srkirkland/archive/2011/03/29/deploy-nuget-packages-during-ci-build-with-teamcity.aspx</link><pubDate>Tue, 29 Mar 2011 15:32:22 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7737811</guid><dc:creator>srkirkland</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7737811</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/03/29/deploy-nuget-packages-during-ci-build-with-teamcity.aspx#comments</comments><description>&lt;p&gt;One great benefit of having a Continuous Integration server like TeamCity (&lt;a title="http://www.jetbrains.com/teamcity/" href="http://www.jetbrains.com/teamcity/"&gt;http://www.jetbrains.com/teamcity/&lt;/a&gt;) building your code is that you can hook into the build process to have it also handle tedious or time-consuming tasks for you, such as running all of your unit tests, code coverage analyses, etc.&lt;/p&gt;  &lt;p&gt;Now that NuGet (&lt;a title="http://nuget.org/" href="http://nuget.org/"&gt;http://nuget.org/&lt;/a&gt;) has arrived and simplified package management in .NET, wouldn’t it be nice to have your CI server build an updated NuGet package for you along with every build?&amp;#160; An why not go one step further and have your build process automatically push the newest version of your package to the central NuGet server (or even your own hosted NuGet server)?&lt;/p&gt;  &lt;p&gt;It turns out this is actually very easy to do – let’s see how.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Super-Quick NuGet Package Introduction&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;If you would like to familiarize yourself with what NuGet is and how to use it, take a look at the project homepage at &lt;a title="http://nuget.codeplex.com/" href="http://nuget.codeplex.com/"&gt;http://nuget.codeplex.com/&lt;/a&gt;.&amp;#160; &lt;/p&gt;  &lt;p&gt;For this post it’s really only necessary to know that a NuGet package starts out as a specification file (*.nupec) and usually some deliverable content (Dlls, script files, etc).&amp;#160; Once you have a specification file, you use the NuGet.exe command line utility to turn it into a package (*.nupkg) that can then be uploaded to the masses via &lt;a href="http://nuget.org/"&gt;http://nuget.org/&lt;/a&gt;.&amp;#160; [Full details are available at &lt;a title="http://nuget.codeplex.com/documentation?title=Creating%20a%20Package" href="http://nuget.codeplex.com/documentation?title=Creating%20a%20Package"&gt;http://nuget.codeplex.com/documentation?title=Creating%20a%20Package&lt;/a&gt;].&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;Building and Deploying Your Package&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;You’ll need to have your *.nuspec file checked into source control, and I also find it useful to check in the nuget.exe command-line utility as well (although this is not necessary as long as it is on your build server).&amp;#160; I tend to put my specifications in a /Build/NuGet folder, so it’s outside of the main /src/ folder.&lt;/p&gt;  &lt;p&gt;Note: The following steps are TeamCity specific, but any build process with the ability to run a batch file should be able to do the same thing.&lt;/p&gt;  &lt;p&gt;1. Open up your project’s build configuration and select #3, “Build Steps.”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_59A2ABDE.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_43D8C381.png" width="257" height="299" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;2. Click “Add Build Step.”&lt;/p&gt;  &lt;p&gt;3. Under Runner Type choose “Command Line,” and then under Run choose “Custom Script.”&amp;#160; You can optionally specify a working directory to have your script run in that directory, which I find to be quite helpful.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_7C173A99.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_6243046A.png" width="533" height="198" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;4.&amp;#160; Now you are ready to write your custom script, which should be able to perform the following steps: (1) cleanup old *.nupack files, (2) create your newest package with the correct version number, and (3) push that package up to nuget.org or another nuget server.&lt;/p&gt;  &lt;p&gt;My script is as follows:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;del *.nupkg&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;NuGet.exe pack Project\Project.nuspec -Version %system.build.number%&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;forfiles /m *.nupkg /c &lt;span class="str"&gt;&amp;quot;cmd /c NuGet.exe push @FILE &amp;lt;your-key&amp;gt;&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;5. That’s all there is to it, just replace &amp;lt;your-key&amp;gt; with your access key from nuget.org (look under MyAccount)&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2853C17E.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_666CDC2F.png" width="769" height="319" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Script Breakdown:&lt;/p&gt;

&lt;p&gt;On line two notice how I use TeamCity’s %system.build.number% to inject the build number into the generated package.&amp;#160; This is very important because NuGet pays close attention to your package version number (as David Ebbo describes in detail in his NuGet versioning blog series &lt;a title="http://blog.davidebbo.com/2011/01/nuget-versioning-part-3-unification-via.html" href="http://blog.davidebbo.com/2011/01/nuget-versioning-part-3-unification-via.html"&gt;http://blog.davidebbo.com/2011/01/nuget-versioning-part-3-unification-via.html&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;The third line is pretty fun—basically it is saying for every file that ends in *.nupkg, call ‘NuGet.exe push &amp;lt;filename&amp;gt; &amp;lt;your-key&amp;gt;’.&amp;#160; I really like this approach, and it could even be adapted to build and push multiple NuGet packages during every build run.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Wrap Up&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Overall there wasn’t too much work to do, we just created a command line script build runner and added a few lines of code to automatically build and push versioned NuGet packages.&lt;/p&gt;

&lt;p&gt;Now that I’m using NuGet a lot more, with one OSS project on nuget.org (&lt;a title="http://dataannotationsextensions.org/" href="http://dataannotationsextensions.org/"&gt;http://dataannotationsextensions.org/&lt;/a&gt;) and several hosted on my own internal company NuGet server, I find this automatic build and deploy process the perfect way to keep my packages up to date.&amp;#160; &lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7737811" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Tips/default.aspx">Tips</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MSBuild/default.aspx">MSBuild</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/NuGet/default.aspx">NuGet</category></item><item><title>Inflector for .NET</title><link>http://weblogs.asp.net/srkirkland/archive/2011/03/15/inflector-for-net.aspx</link><pubDate>Tue, 15 Mar 2011 16:17:05 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7724299</guid><dc:creator>srkirkland</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7724299</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/03/15/inflector-for-net.aspx#comments</comments><description>&lt;p&gt;I was writing conventions for FluentNHibernate the other day and I ran into the need to pluralize a given string and immediately thought of the ruby on rails Inflector.&amp;#160; It turns out there is a .NET library out there also capable of doing word inflection, originally written (I believe) by Andrew Peters, though the link I had no longer works.&amp;#160; The entire Inflector class is only a little over 200 lines long and can be easily included into any project, and contains the Pluralize() method along with a few other helpful methods (like Singularize(), Camelize(), Capitalize(), etc).&lt;/p&gt;  &lt;p&gt;The Inflector class is available in its entirety from my github repository &lt;a title="https://github.com/srkirkland/Inflector" href="https://github.com/srkirkland/Inflector"&gt;https://github.com/srkirkland/Inflector&lt;/a&gt;.&amp;#160; In addition to the &lt;a href="https://github.com/srkirkland/Inflector/blob/master/Inflector/Inflector.cs" target="_blank"&gt;Inflector.cs&lt;/a&gt; class I added tests for every single method available so you can gain an understanding of what each method does.&amp;#160; Also, if you are wondering about a specific test case feel free to fork my project and add your own test cases to ensure Inflector does what you expect.&lt;/p&gt;  &lt;p&gt;Here is an example of some test cases for pluralize:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;quiz&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;quizzes&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;perspective&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;perspectives&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;ox&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;oxen&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;buffalo&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;buffaloes&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;tomato&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;tomatoes&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;dwarf&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;dwarves&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;elf&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;elves&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;mouse&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;mice&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;octopus&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;octopi&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;vertex&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;vertices&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;matrix&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;matrices&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;rice&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;rice&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;TestData.Add(&lt;span class="str"&gt;&amp;quot;shoe&amp;quot;&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;shoes&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Pretty smart stuff.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7724299" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Tips/default.aspx">Tips</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category></item><item><title>Adding Unobtrusive Validation To MVCContrib Fluent Html</title><link>http://weblogs.asp.net/srkirkland/archive/2011/03/08/adding-unobtrusive-validation-to-mvccontrib-fluent-html.aspx</link><pubDate>Tue, 08 Mar 2011 18:05:10 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7717931</guid><dc:creator>srkirkland</dc:creator><slash:comments>6</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7717931</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/03/08/adding-unobtrusive-validation-to-mvccontrib-fluent-html.aspx#comments</comments><description>&lt;p&gt;ASP.NET MVC 3 includes a new unobtrusive validation strategy that utilizes HTML5 data-* attributes to decorate form elements.&amp;#160; Using a combination of jQuery validation and an unobtrusive validation adapter script that comes with MVC 3, those attributes are then turned into client side validation rules.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;A Quick Introduction to Unobtrusive Validation&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;To quickly show how this works in practice, assume you have the following Order.cs class (think Northwind) [If you are familiar with unobtrusive validation in MVC 3 you can skip to the next section]:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Order : DomainObject&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [DataType(DataType.Date)]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; DateTime OrderDate { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [Required]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [StringLength(12)]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ShipAddress { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [Required]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;virtual&lt;/span&gt; Customer OrderedBy { get; set; }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Note the System.ComponentModel.DataAnnotations attributes, which provide the validation and metadata information used by ASP.NET MVC 3 to determine how to render out these properties.&amp;#160; Now let’s assume we have a form which can edit this Order class, specifically let’s look at the ShipAddress property:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;@Html.LabelFor(x =&amp;gt; x.Order.ShipAddress)&lt;/pre&gt;

  &lt;pre&gt;@Html.EditorFor(x =&amp;gt; x.Order.ShipAddress)&lt;/pre&gt;

  &lt;pre class="alt"&gt;@Html.ValidationMessageFor(x =&amp;gt; x.Order.ShipAddress)&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now the Html.EditorFor() method is smart enough to look at the ShipAddress attributes and write out the necessary unobtrusive validation html attributes.&amp;#160; Note we could have used Html.TextBoxFor() or even Html.TextBox() and still retained the same results.&lt;/p&gt;

&lt;p&gt;If we view source on the input box generated by the Html.EditorFor() call, we get the following:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Rua do Paço, 67&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order.ShipAddress&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="attr"&gt;data-val-required&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;The ShipAddress field is required.&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;data-val-length-max&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;12&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="attr"&gt;data-val-length&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;The field ShipAddress must be a string with a maximum length of 12.&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="attr"&gt;data-val&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text-box single-line input-validation-error&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;As you can see, we have data-val-* attributes for both required and length, along with the proper error messages and additional data as necessary (in this case, we have the length-max=”12”).&lt;/p&gt;

&lt;p&gt;And of course, if we try to submit the form with an invalid value, we get an error on the client:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2942D034.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_2C088527.png" width="664" height="51" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Working with MvcContrib’s Fluent Html &lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;
  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;&lt;/p&gt;

  &lt;p&gt;The &lt;a href="http://mvccontrib.codeplex.com/" target="_blank"&gt;MvcContrib&lt;/a&gt; project offers a fluent interface for creating Html elements which I find very expressive and useful, especially when it comes to creating select lists.&amp;#160; Let’s look at a few quick examples:&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;@&lt;span class="kwrd"&gt;this&lt;/span&gt;.TextBox(x =&amp;gt; x.FirstName).Class(&lt;span class="str"&gt;&amp;quot;required&amp;quot;&lt;/span&gt;).Label(&lt;span class="str"&gt;&amp;quot;First Name:&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;@&lt;span class="kwrd"&gt;this&lt;/span&gt;.MultiSelect(x =&amp;gt; x.UserId).Options(ViewModel.Users)&lt;/pre&gt;

    &lt;pre class="alt"&gt;@&lt;span class="kwrd"&gt;this&lt;/span&gt;.CheckBox(&lt;span class="str"&gt;&amp;quot;enabled&amp;quot;&lt;/span&gt;).LabelAfter(&lt;span class="str"&gt;&amp;quot;Enabled&amp;quot;&lt;/span&gt;).Title(&lt;span class="str"&gt;&amp;quot;Click to enable.&amp;quot;&lt;/span&gt;).Styles(vertical_align =&amp;gt; &lt;span class="str"&gt;&amp;quot;middle&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;@(&lt;span class="kwrd"&gt;this&lt;/span&gt;.Select(&lt;span class="str"&gt;&amp;quot;Order.OrderedBy&amp;quot;&lt;/span&gt;).Options(Model.Customers, x =&amp;gt; x.Id, x =&amp;gt; x.CompanyName)&lt;/pre&gt;

    &lt;pre&gt;                    .Selected(Model.Order.OrderedBy != &lt;span class="kwrd"&gt;null&lt;/span&gt; ? Model.Order.OrderedBy.Id : &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    .FirstOption(&lt;span class="kwrd"&gt;null&lt;/span&gt;, &lt;span class="str"&gt;&amp;quot;--Select A Company--&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre&gt;                    .HideFirstOptionWhen(Model.Order.OrderedBy != &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;

    &lt;pre class="alt"&gt;                    .Label(&lt;span class="str"&gt;&amp;quot;Ordered By:&amp;quot;&lt;/span&gt;))&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;These fluent html helpers create the normal html you would expect, and I think they make life a lot easier and more readable when dealing with complex markup or select list data models (look ma: no anonymous objects for creating class names!).&lt;/p&gt;

  &lt;p&gt;Of course, the problem we have now is that MvcContrib’s fluent html helpers don’t know about ASP.NET MVC 3’s unobtrusive validation attributes and thus don’t take part in client validation on your page.&amp;#160; This is not ideal, so I wrote a quick helper method to extend fluent html with the knowledge of what unobtrusive validation attributes to include when they are rendered.&lt;/p&gt;

  &lt;h3&gt;&lt;u&gt;Extending MvcContrib’s Fluent Html&lt;/u&gt;&lt;/h3&gt;

  &lt;p&gt;Before posting the code, there are just a few things you need to know.&amp;#160; The first is that all Fluent Html elements implement the IElement interface (MvcContrib.FluentHtml.Elements.IElement), and the second is that the base System.Web.Mvc.HtmlHelper has been extended with a method called GetUnobtrusiveValidationAttributes which we can use to determine the necessary attributes to include.&amp;#160; With this knowledge we can make quick work of extending fluent html:&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FluentHtmlExtensions&lt;/pre&gt;

    &lt;pre&gt;{&lt;/pre&gt;

    &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; T IncludeUnobtrusiveValidationAttributes&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; T element, HtmlHelper htmlHelper) &lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;where&lt;/span&gt; T : MvcContrib.FluentHtml.Elements.IElement&lt;/pre&gt;

    &lt;pre class="alt"&gt;    {&lt;/pre&gt;

    &lt;pre&gt;        IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; validationAttributes = htmlHelper&lt;/pre&gt;

    &lt;pre class="alt"&gt;            .GetUnobtrusiveValidationAttributes(element.GetAttr(&lt;span class="str"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;));&lt;/pre&gt;

    &lt;pre&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var validationAttribute &lt;span class="kwrd"&gt;in&lt;/span&gt; validationAttributes)&lt;/pre&gt;

    &lt;pre&gt;        {&lt;/pre&gt;

    &lt;pre class="alt"&gt;            element.SetAttr(validationAttribute.Key, validationAttribute.Value);&lt;/pre&gt;

    &lt;pre&gt;        }&lt;/pre&gt;

    &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

    &lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; element;&lt;/pre&gt;

    &lt;pre class="alt"&gt;    }&lt;/pre&gt;

    &lt;pre&gt;}&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;The code is pretty straight forward – basically we use a passed HtmlHelper to get a list of validation attributes for the current element and then add each of the returned attributes to the element to be rendered.&lt;/p&gt;

  &lt;h3&gt;&lt;u&gt;The Extension In Action&lt;/u&gt;&lt;/h3&gt;

  &lt;p&gt;Now let’s get back to the earlier ShipAddress example and see what we’ve accomplished.&amp;#160; First we will use a fluent html helper to render out the ship address text input (this is the ‘before’ case):&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;@&lt;span class="kwrd"&gt;this&lt;/span&gt;.TextBox(&lt;span class="str"&gt;&amp;quot;Order.ShipAddress&amp;quot;&lt;/span&gt;).Label(&lt;span class="str"&gt;&amp;quot;Ship Address:&amp;quot;&lt;/span&gt;).Class(&lt;span class="str"&gt;&amp;quot;class-name&amp;quot;&lt;/span&gt;)&lt;/pre&gt;
  &lt;/div&gt;
  &lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

  &lt;p&gt;And the resulting HTML:&lt;/p&gt;

  &lt;div class="csharpcode"&gt;
    &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress_Label&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;for&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Ship Address:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Rua do Paço, 67&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order.ShipAddress&amp;quot;&lt;/span&gt;&lt;/pre&gt;

    &lt;pre class="alt"&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;class-name&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Now let’s do the same thing except here we’ll use the newly written extension method:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;@&lt;span class="kwrd"&gt;this&lt;/span&gt;.TextBox(&lt;span class="str"&gt;&amp;quot;Order.ShipAddress&amp;quot;&lt;/span&gt;).Label(&lt;span class="str"&gt;&amp;quot;Ship Address:&amp;quot;&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;.Class(&lt;span class="str"&gt;&amp;quot;class-name&amp;quot;&lt;/span&gt;).IncludeUnobtrusiveValidationAttributes(Html)&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;And the resulting HTML:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress_Label&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;for&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Ship Address:&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;label&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Rua do Paço, 67&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order.ShipAddress&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Order_ShipAddress&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;data-val-required&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;The ShipAddress field is required.&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt; &lt;span class="attr"&gt;data-val-length-max&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;12&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;span class="attr"&gt;data-val-length&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;The field ShipAddress must be a string with a maximum length of 12.&amp;quot;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt; &lt;span class="attr"&gt;data-val&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;class-name&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Excellent!&amp;#160; Now we can continue to use unobtrusive validation and have the flexibility to use ASP.NET MVC’s Html helpers or MvcContrib’s fluent html helpers interchangeably, and every element will participate in client side validation.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2942D034.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_2C088527.png" width="664" height="51" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Wrap Up&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Overall I’m happy with this solution, although in the best case scenario MvcContrib would know about unobtrusive validation attributes and include them automatically (of course if it is enabled in the web.config file).&amp;#160; I know that MvcContrib allows you to author global behaviors, but that requires changing the base class of your views, which I am not willing to do.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7717931" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Data+Annotations/default.aspx">Data Annotations</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MvcContrib/default.aspx">MvcContrib</category></item><item><title>Introducing Data Annotations Extensions</title><link>http://weblogs.asp.net/srkirkland/archive/2011/02/23/introducing-data-annotations-extensions.aspx</link><pubDate>Wed, 23 Feb 2011 16:12:40 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7711580</guid><dc:creator>srkirkland</dc:creator><slash:comments>65</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7711580</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/02/23/introducing-data-annotations-extensions.aspx#comments</comments><description>&lt;p&gt;Validation of user input is integral to building a modern web application, and ASP.NET MVC offers us a way to enforce business rules on both the client and server using Model Validation.&amp;#160; The recent release of ASP.NET MVC 3 has improved these offerings on the client side by introducing an unobtrusive validation library built on top of jquery.validation.&amp;#160; Out of the box MVC comes with support for Data Annotations (that is, System.ComponentModel.DataAnnotations) and can be extended to support other frameworks.&amp;#160; Data Annotations Validation is becoming more popular and is being baked in to many other Microsoft offerings, including Entity Framework, though with MVC it only contains four validators: Range, Required, StringLength and Regular Expression.&amp;#160; The Data Annotations Extensions project attempts to augment these validators with additional attributes while maintaining the clean integration Data Annotations provides.&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;A Quick Word About Data Annotations Extensions&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;The Data Annotations Extensions project can be found at &lt;a title="http://dataannotationsextensions.org/" href="http://dataannotationsextensions.org/"&gt;http://dataannotationsextensions.org/&lt;/a&gt;, and currently provides 11 additional validation attributes (ex: Email, EqualTo, Min/Max) on top of Data Annotations’ original 4.&amp;#160; You can find a current list of the validation attributes on the afore mentioned website.&lt;/p&gt;  &lt;p&gt;The core library provides server-side validation attributes that can be used in any .NET 4.0 project (no MVC dependency). There is also an easily pluggable client-side validation library which can be used in ASP.NET MVC 3 projects using unobtrusive jquery validation (only MVC3 included javascript files are required).&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;On to the Preview&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Let’s say you had the following “Customer” domain model (or view model, depending on your project structure) in an MVC 3 project:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;  Email { get; set; }&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ProfilePictureLocation { get; set; }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;When it comes time to create/edit this Customer, you will probably have a CustomerController and a simple form that just uses one of the Html.EditorFor() methods that the ASP.NET MVC tooling generates for you (or you can write yourself).&amp;#160; It should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_6BB710F5.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_71FDE783.png" width="231" height="293" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;With no validation, the customer can enter nonsense for an email address, and then can even report their age as a negative number!&amp;#160; With the built-in Data Annotations validation, I could do a bit better by adding a Range to the age, adding a RegularExpression for email (yuck!), and adding some required attributes.&amp;#160; However, I’d still be able to report my age as 10.75 years old, and my profile picture could still be any string.&amp;#160; Let’s use Data Annotations along with this project, Data Annotations Extensions, and see what we can get:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Customer&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Email]&lt;/pre&gt;

  &lt;pre&gt;    [Required]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;  Email { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Integer]&lt;/pre&gt;

  &lt;pre&gt;    [Min(1, ErrorMessage=&lt;span class="str"&gt;&amp;quot;Unless you are benjamin button you are lying.&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Required]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [FileExtensions(&lt;span class="str"&gt;&amp;quot;png|jpg|jpeg|gif&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ProfilePictureLocation { get; set; }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now let’s try to put in some invalid values and see what happens:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_5F48EDCC.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_77002532.png" width="786" height="284" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;That is very nice validation, all done on the client side (will also be validated on the server).&amp;#160; Also, the Customer class validation attributes are very easy to read and understand.&lt;/p&gt;

&lt;p&gt;Another bonus: Since Data Annotations Extensions can integrate with MVC 3’s unobtrusive validation, no additional scripts are required!&lt;/p&gt;

&lt;p&gt;Now that we’ve seen our target, let’s take a look at how to get there within a new MVC 3 project.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Adding Data Annotations Extensions To Your Project&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;First we will File-&amp;gt;New Project and create an ASP.NET MVC 3 project.&amp;#160; I am going to use Razor for these examples, but any view engine can be used in practice.&amp;#160; &lt;/p&gt;

&lt;p&gt;Now go into the NuGet Extension Manager (right click on references and select add Library Package Reference) and search for “DataAnnotationsExtensions.”&amp;#160; You should see the following two packages:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_1642CC06.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_22D07922.png" width="896" height="384" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The first package is for server-side validation scenarios, but since we are using MVC 3 and would like comprehensive sever and client validation support, click on the DataAnnotationsExtensions.MVC3 project and then click Install.&amp;#160; This will install the Data Annotations Extensions server and client validation DLLs along with David Ebbo’s web activator (which enables the validation attributes to be registered with MVC 3).&lt;/p&gt;

&lt;p&gt;Now that Data Annotations Extensions is installed you have all you need to start doing advanced model validation.&amp;#160; If you are already using Data Annotations in your project, just making use of the additional validation attributes will provide client and server validation automatically.&amp;#160; However, assuming you are starting with a blank project I’ll walk you through setting up a controller and model to test with.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Creating Your Model&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;In the Models folder, create a new User.cs file with a User class that you can use as a model.&amp;#160; To start with, I’ll use the following class:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; User&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Email { get; set; }&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Password { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; PasswordConfirm { get; set; }&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; HomePage { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Next, create a simple controller with at least a Create method, and then a matching Create view (note, you can do all of this via the MVC built-in tooling).&amp;#160; Your files will look something like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;UserController.cs&lt;/em&gt;:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; UserController : Controller&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Create()&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; View(&lt;span class="kwrd"&gt;new&lt;/span&gt; User());&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [HttpPost]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Create(User user)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!ModelState.IsValid)&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; View(user);&lt;/pre&gt;

  &lt;pre&gt;        }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; Content(&lt;span class="str"&gt;&amp;quot;User valid!&amp;quot;&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;em&gt;Create.cshtml&lt;/em&gt;:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;@model NuGetValidationTester.Models.User&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;@{&lt;/pre&gt;

  &lt;pre&gt;    ViewBag.Title = &lt;span class="str"&gt;&amp;quot;Create&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;lt;h2&amp;gt;Create&amp;lt;/h2&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;lt;script src=&lt;span class="str"&gt;&amp;quot;@Url.Content(&amp;quot;&lt;/span&gt;~/Scripts/jquery.validate.min.js&lt;span class="str"&gt;&amp;quot;)&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;lt;script src=&lt;span class="str"&gt;&amp;quot;@Url.Content(&amp;quot;&lt;/span&gt;~/Scripts/jquery.validate.unobtrusive.min.js&lt;span class="str"&gt;&amp;quot;)&amp;quot;&lt;/span&gt; type=&lt;span class="str"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;@&lt;span class="kwrd"&gt;using&lt;/span&gt; (Html.BeginForm()) {&lt;/pre&gt;

  &lt;pre class="alt"&gt;    @Html.ValidationSummary(&lt;span class="kwrd"&gt;true&lt;/span&gt;)&lt;/pre&gt;

  &lt;pre&gt;    &amp;lt;fieldset&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &amp;lt;legend&amp;gt;User&amp;lt;/legend&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;/pre&gt;

  &lt;pre class="alt"&gt;        @Html.EditorForModel()&lt;/pre&gt;

  &lt;pre&gt;        &lt;/pre&gt;

  &lt;pre class="alt"&gt;        &amp;lt;p&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;            &amp;lt;input type=&lt;span class="str"&gt;&amp;quot;submit&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt;=&lt;span class="str"&gt;&amp;quot;Create&amp;quot;&lt;/span&gt; /&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &amp;lt;/p&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;    &amp;lt;/fieldset&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;In the Create.cshtml view, note that we are referencing jquery validation and jquery unobtrusive (jquery is referenced in the layout page).&amp;#160; These MVC 3 included scripts are the only ones you need to enjoy both the basic Data Annotations validation as well as the validation additions available in Data Annotations Extensions.&amp;#160; These references are added by default when you use the MVC 3 “Add View” dialog on a modification template type.&lt;/p&gt;

&lt;p&gt;Now when we go to /User/Create we should see a form for editing a User&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2CB56A8D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_0104A091.png" width="256" height="399" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Since we haven’t yet added any validation attributes, this form is valid as shown (including no password, email and an age of 0).&amp;#160; With the built-in Data Annotations attributes we can make some of the fields required, and we could use a range validator of maybe 1 to 110 on Age (of course we don’t want to leave out supercentenarians) but let’s go further and validate our input comprehensively using Data Annotations Extensions.&amp;#160; The new and improved User.cs model class.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;    [Required]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Email]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Email { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [Required]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Password { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Required]&lt;/pre&gt;

  &lt;pre&gt;    [EqualTo(&lt;span class="str"&gt;&amp;quot;Password&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; PasswordConfirm { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Url]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; HomePage { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [Integer]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [Min(1)]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now let’s re-run our form and try to use some invalid values:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2B70D1AE.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_78A0CB39.png" width="622" height="390" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;All of the validation errors you see above occurred on the client, without ever even hitting submit.&amp;#160; The validation is also checked on the server, which is a good practice since client validation is easily bypassed.&lt;/p&gt;

&lt;p&gt;That’s all you need to do to start a new project and include Data Annotations Extensions, and of course you can integrate it into an existing project just as easily.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Nitpickers Corner&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;ASP.NET MVC 3 futures defines four new data annotations attributes which this project has as well: CreditCard, Email, Url and EqualTo.&amp;#160; Unfortunately referencing MVC 3 futures necessitates taking an dependency on MVC 3 in your model layer, which may be unadvisable in a multi-tiered project.&amp;#160; Data Annotations Extensions keeps the server and client side libraries separate so using the project’s validation attributes don’t require you to take any additional dependencies in your model layer which still allowing for the rich client validation experience if you are using MVC 3.&lt;/p&gt;

&lt;p&gt;Custom Error Message and Globalization: Since the Data Annotations Extensions are build on top of Data Annotations, you have the ability to define your own static error messages and even to use resource files for very customizable error messages.&lt;/p&gt;

&lt;p&gt;Available Validators: Please see the project site at &lt;a title="http://dataannotationsextensions.org/" href="http://dataannotationsextensions.org/"&gt;http://dataannotationsextensions.org/&lt;/a&gt; for an up-to-date list of the new validators included in this project.&amp;#160; As of this post, the following validators are available:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;CreditCard &lt;/li&gt;

  &lt;li&gt;Date &lt;/li&gt;

  &lt;li&gt;Digits &lt;/li&gt;

  &lt;li&gt;Email &lt;/li&gt;

  &lt;li&gt;EqualTo &lt;/li&gt;

  &lt;li&gt;FileExtensions &lt;/li&gt;

  &lt;li&gt;Integer &lt;/li&gt;

  &lt;li&gt;Max &lt;/li&gt;

  &lt;li&gt;Min &lt;/li&gt;

  &lt;li&gt;Numeric &lt;/li&gt;

  &lt;li&gt;Url &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;&lt;u&gt;Conclusion&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Hopefully I’ve illustrated how easy it is to add server and client validation to your MVC 3 projects, and how to easily you can extend the available validation options to meet real world needs.&lt;/p&gt;

&lt;p&gt;The Data Annotations Extensions project is fully open source under the BSD license.&amp;#160; Any feedback would be greatly appreciated.&amp;#160; More information than you require, along with links to the source code, is available at &lt;a title="http://dataannotationsextensions.org/" href="http://dataannotationsextensions.org/"&gt;http://dataannotationsextensions.org/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7711580" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Tips/default.aspx">Tips</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/jQuery/default.aspx">jQuery</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Data+Annotations/default.aspx">Data Annotations</category></item><item><title>Adding Client Validation To DataAnnotations DataType Attribute</title><link>http://weblogs.asp.net/srkirkland/archive/2011/02/15/adding-client-validation-to-dataannotations-datatype-attribute.aspx</link><pubDate>Tue, 15 Feb 2011 16:38:07 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7706219</guid><dc:creator>srkirkland</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7706219</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2011/02/15/adding-client-validation-to-dataannotations-datatype-attribute.aspx#comments</comments><description>&lt;p&gt;The System.ComponentModel.DataAnnotations namespace contains a validation attribute called DataTypeAttribute, which takes an enum specifying what data type the given property conforms to.&amp;#160; Here are a few quick examples:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DataTypeEntity&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [DataType(DataType.Date)]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime DateTime { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    [DataType(DataType.EmailAddress)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; EmailAddress { get; set; }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;This attribute comes in handy when using ASP.NET MVC, because the type you specify will determine what “template” MVC uses.&amp;#160; Thus, for the DateTime property if you create a partial in Views/[loc]/EditorTemplates/Date.ascx (or cshtml for razor), that view will be used to render the property when using any of the Html.EditorFor() methods.&lt;/p&gt;

&lt;p&gt;One thing that the DataType() validation attribute does not do is any actual validation.&amp;#160; To see this, let’s take a look at the EmailAddress property above.&amp;#160; It turns out that regardless of the value you provide, the entity will be considered valid:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="rem"&gt;//valid&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;new&lt;/span&gt; DataTypeEntity {EmailAddress = &lt;span class="str"&gt;&amp;quot;Foo&amp;quot;&lt;/span&gt;};&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_655B625E.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_0093BB60.png" width="219" height="53" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Hmmm.&amp;#160; Since DataType() doesn’t validate, that leaves us with two options: (1) Create our own attributes for each datatype to validate, like [Date], or (2) add validation into the DataType attribute directly.&amp;#160; &lt;/p&gt;

&lt;p&gt;In this post, I will show you how to hookup client-side validation to the existing DataType() attribute for a desired type.&amp;#160; From there adding server-side validation would be a breeze and even writing a custom validation attribute would be simple (more on that in future posts).&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Validation All The Way Down&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Our goal will be to leave our DataTypeEntity class (from above) untouched, requiring no reference to System.Web.Mvc.&amp;#160; Then we will make an ASP.NET MVC project that allows us to create a new DataTypeEntity and hookup automatic client-side date validation using the suggested “out-of-the-box” jquery.validate bits that are included with ASP.NET MVC 3.&amp;#160; For simplicity I’m going to focus on the only DateTime field, but the concept is generally the same for any other DataType.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_7FBB5575.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_633E6395.png" width="454" height="60" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Building a DataTypeAttribute Adapter&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;To start we will need to build a new validation adapter that we can register using ASP.NET MVC’s DataAnnotationsModelValidatorProvider.RegisterAdapter() method.&amp;#160; This method takes two Type parameters; The first is the attribute we are looking to validate with and the second is an adapter that should subclass System.Web.Mvc.ModelValidator.&lt;/p&gt;

&lt;p&gt;Since we are extending DataAnnotations we can use the subclass of ModelValidator called DataAnnotationsModelValidator&amp;lt;&amp;gt;.&amp;#160; This takes a generic argument of type DataAnnotations.ValidationAttribute, which lucky for us means the DataTypeAttribute will fit in nicely.&lt;/p&gt;

&lt;p&gt;So starting from there and implementing the required constructor, we get:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DataTypeAttributeAdapter : DataAnnotationsModelValidator&amp;lt;DataTypeAttribute&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DataTypeAttributeAdapter(ModelMetadata metadata, ControllerContext context, DataTypeAttribute attribute)&lt;/pre&gt;

  &lt;pre&gt;        : &lt;span class="kwrd"&gt;base&lt;/span&gt;(metadata, context, attribute) { }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now you have a full-fledged validation adapter, although it doesn’t do anything yet.&amp;#160; There are two methods you can override to add functionality, IEnumerable&amp;lt;ModelValidationResult&amp;gt; Validate(object container) and IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules().&amp;#160; Adding logic to the server-side Validate() method is pretty straightforward, and for this post I’m going to focus on GetClientValidationRules().&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Adding a Client Validation Rule&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Adding client validation is now incredibly easy because jquery.validate is very powerful and already comes with a ton of validators (including date and regular expressions for our email example).&amp;#160; Teamed with the new unobtrusive validation javascript support we can make short work of our ModelClientValidationDateRule:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ModelClientValidationDateRule : ModelClientValidationRule&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; ModelClientValidationDateRule(&lt;span class="kwrd"&gt;string&lt;/span&gt; errorMessage)&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        ErrorMessage = errorMessage;&lt;/pre&gt;

  &lt;pre&gt;        ValidationType = &lt;span class="str"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;If your validation has additional parameters you can the ValidationParameters IDictionary&amp;lt;string,object&amp;gt; to include them.&amp;#160; There is a little bit of conventions magic going on here, but the distilled version is that we are defining a “date” validation type, which will be included as html5 data-* attributes (specifically data-val-date).&amp;#160; Then jquery.validate.unobtrusive takes this attribute and basically passes it along to jquery.validate, which knows how to handle date validation.&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Finishing our DataTypeAttribute Adapter&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Now that we have a model client validation rule, we can return it in the GetClientValidationRules() method of our DataTypeAttributeAdapter created above.&amp;#160; Basically I want to say if DataType.Date was provided, then return the date rule with a given error message (using ValidationAttribute.FormatErrorMessage()).&amp;#160; The entire adapter is below:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DataTypeAttributeAdapter : DataAnnotationsModelValidator&amp;lt;DataTypeAttribute&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DataTypeAttributeAdapter(ModelMetadata metadata, ControllerContext context, DataTypeAttribute attribute)&lt;/pre&gt;

  &lt;pre&gt;        : &lt;span class="kwrd"&gt;base&lt;/span&gt;(metadata, context, attribute) { }&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; System.Collections.Generic.IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules()&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (Attribute.DataType == DataType.Date)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt;[] { &lt;span class="kwrd"&gt;new&lt;/span&gt; ModelClientValidationDateRule(Attribute.FormatErrorMessage(Metadata.GetDisplayName())) };&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;base&lt;/span&gt;.GetClientValidationRules();&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;h3&gt;&lt;u&gt;Putting it all together&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Now that we have an adapter for the DataTypeAttribute, we just need to tell ASP.NET MVC to use it.&amp;#160; The easiest way to do this is to use the built in DataAnnotationsModelValidatorProvider by calling RegisterAdapter() in your global.asax startup method.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;DataAnnotationsModelValidatorProvider.RegisterAdapter(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(DataTypeAttribute), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(DataTypeAttributeAdapter));&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Show and Tell&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Let’s see this in action using a clean ASP.NET MVC 3 project.&amp;#160; First make sure to reference the jquery, jquery.vaidate and jquery.validate.unobtrusive scripts that you will need for client validation.&lt;/p&gt;

&lt;p&gt;Next, let’s make a model class (note we are using the same built-in DataType() attribute that comes with System.ComponentModel.DataAnnotations).&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DataTypeEntity&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    [DataType(DataType.Date, ErrorMessage = &lt;span class="str"&gt;&amp;quot;Please enter a valid date (ex: 2/14/2011)&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTime DateTime { get; set; }&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Then we make a create page with a strongly-typed DataTypeEntity model, the form section is shown below (notice we are just using EditorForModel):&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;@using (Html.BeginForm()) {&lt;/pre&gt;

  &lt;pre&gt;    @Html.ValidationSummary(true)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Fields&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;legend&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        @Html.EditorForModel()&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;submit&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Create&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;p&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;fieldset&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;The final step is to register the adapter in our global.asax file: &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;DataAnnotationsModelValidatorProvider.RegisterAdapter(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(DataTypeAttribute), &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(DataTypeAttributeAdapter));&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Now we are ready to run the page:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_17728CDC.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_7D9E56AC.png" width="242" height="201" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Looking at the datetime field’s html, we see that our adapter added some data-* validation attributes:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;input&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;value&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1/1/0001&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DateTime&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;DateTime&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;   &lt;span class="attr"&gt;data-val-required&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;The DateTime field is required.&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre class="alt"&gt;   &lt;span class="attr"&gt;data-val-date&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Please enter a valid date (ex: 2/14/2011)&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;data-val&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;   &lt;span class="attr"&gt;class&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text-box single-line valid&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Here data-val-required was added automatically because DateTime is non-nullable, and data-val-date was added by our validation adapter.&amp;#160; Now if we try to add an invalid date:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_63CA207D.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_030CC751.png" width="506" height="198" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Our custom error message is displayed via client-side validation as soon as we tab out of the box.&amp;#160; If we didn’t include a custom validation message, the default DataTypeAttribute “The field {0} is invalid” would have been shown (of course we can change the default as well).&amp;#160; Note we did not specify server-side validation, but in this case we don’t have to because an invalid date will cause a server-side error during model binding.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Conclusion&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;I really like how easy it is to register new data annotations model validators, whether they are your own or, as in this post, supplements to existing validation attributes.&amp;#160; I’m still debating about whether adding the validation directly in the DataType attribute is the correct place to put it versus creating a dedicated “Date” validation attribute, but it’s nice to know either option is available and, as we’ve seen, simple to implement.&lt;/p&gt;

&lt;p&gt;I’m also working through the nascent stages of an open source project that will create validation attribute extensions to the existing data annotations providers using similar techniques as seen above (examples: Email, Url, EqualTo, Min, Max, CreditCard, etc).&amp;#160; Keep an eye on this blog and subscribe to my twitter feed (@srkirkland) if you are interested for announcements.&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7706219" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/jQuery/default.aspx">jQuery</category></item><item><title>Simple MSBuild Configuration: Updating Assemblies With A Version Number</title><link>http://weblogs.asp.net/srkirkland/archive/2010/12/07/simple-msbuild-configuration-updating-assemblies-with-a-version-number.aspx</link><pubDate>Tue, 07 Dec 2010 18:11:56 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7657799</guid><dc:creator>srkirkland</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7657799</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2010/12/07/simple-msbuild-configuration-updating-assemblies-with-a-version-number.aspx#comments</comments><description>&lt;p&gt;When distributing a library you often run up against versioning problems, once facet of which is simply determining which version of that library your client is running.&amp;#160; Of course, each project in your solution has an AssemblyInfo.cs file which provides, among other things, the ability to set the Assembly name and version number.&amp;#160; Unfortunately, setting the assembly version here would require not only changing the version manually for each build (depending on your schedule), but keeping it in sync across all projects.&amp;#160; &lt;/p&gt;  &lt;p&gt;There are many ways to solve this versioning problem, and in this blog post I’m going to try to explain what I think is the easiest and most flexible solution.&amp;#160; I will walk you through using MSBuild to create a simple build script, and I’ll even show how to (optionally) integrate with a &lt;a href="http://www.jetbrains.com/teamcity/"&gt;Team City&lt;/a&gt; build server.&amp;#160; All of the code from this post can be found at &lt;a title="https://github.com/srkirkland/BuildVersion" href="https://github.com/srkirkland/BuildVersion"&gt;https://github.com/srkirkland/BuildVersion&lt;/a&gt;.&lt;/p&gt;  &lt;h4&gt;&lt;u&gt;Create CommonAssemblyInfo.cs&lt;/u&gt;&lt;/h4&gt;  &lt;p&gt;The first step is to create a common location for the repeated assembly info that is spread across all of your projects.&amp;#160; Create a new solution-level file (I usually create a Build/ folder in the solution root, but anywhere reachable by all your projects will do) called CommonAssemblyInfo.cs.&amp;#160; In here you can put any information common to all your assemblies, including the version number.&amp;#160; An example CommonAssemblyInfo.cs is as follows:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Resources;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Runtime.InteropServices;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: AssemblyCompany(&lt;span class="str"&gt;&amp;quot;University of California, Davis&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;[assembly: AssemblyProduct(&lt;span class="str"&gt;&amp;quot;BuildVersionTest&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: AssemblyCopyright(&lt;span class="str"&gt;&amp;quot;Scott Kirkland &amp;amp; UC Regents&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;[assembly: AssemblyConfiguration(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: AssemblyTrademark(&lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: ComVisible(&lt;span class="kwrd"&gt;false&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: AssemblyVersion(&lt;span class="str"&gt;&amp;quot;1.2.3.4&amp;quot;&lt;/span&gt;)] &lt;span class="rem"&gt;//Will be replaced&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: NeutralResourcesLanguage(&lt;span class="str"&gt;&amp;quot;en-US&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;&lt;u&gt;Cleanup AssemblyInfo.cs &amp;amp; Link CommonAssemblyInfo.cs&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;For each of your projects, you’ll want to clean up your assembly info to contain only information that is unique to that assembly – everything else will go in the CommonAssemblyInfo.cs file.&amp;#160; For most of my projects, that just means setting the AssemblyTitle, though you may feel AssemblyDescription is warranted.&amp;#160; An example AssemblyInfo.cs file is as follows:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;[assembly: AssemblyTitle(&lt;span class="str"&gt;&amp;quot;BuildVersionTest&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Next, you need to “link” the CommonAssemblyinfo.cs file into your projects right beside your newly lean AssemblyInfo.cs file.&amp;#160; To do this, right click on your project and choose Add | Existing Item from the context menu.&amp;#160; Navigate to your CommonAssemblyinfo.cs file but instead of clicking Add, click the little down-arrow next to add and choose “Add as Link.”&amp;#160; You should see a little link graphic similar to this: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_7955D1AD.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1FB7B4F9.png" width="211" height="59" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;We’ve actually reduced complexity a lot already, because if you build all of your assemblies will have the same common info, including the product name and our static (fake) assembly version.&amp;#160; Let’s take this one step further and introduce a build script.&lt;/p&gt;

&lt;h4&gt;&lt;u&gt;Create an MSBuild file&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;What we want from the build script (for now) is basically just to have the common assembly version number changed via a parameter (eventually to be passed in by the build server) and then for the project to build.&amp;#160; Also we’d like to have a flexibility to define what build configuration to use (debug, release, etc).&lt;/p&gt;

&lt;p&gt;In order to find/replace the version number, we are going to use a Regular Expression to find and replace the text within your CommonAssemblyInfo.cs file.&amp;#160; There are many other ways to do this using community build task add-ins, but since we want to keep it simple let’s just define the Regular Expression task manually in a new file, Build.tasks (this example taken from the NuGet build.tasks file).&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Project&lt;/span&gt; &lt;span class="attr"&gt;ToolsVersion&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;4.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DefaultTargets&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Go&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;UsingTask&lt;/span&gt; &lt;span class="attr"&gt;TaskName&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;RegexTransform&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;TaskFactory&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;CodeTaskFactory&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;AssemblyFile&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ParameterGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Items&lt;/span&gt; &lt;span class="attr"&gt;ParameterType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Build.Framework.ITaskItem[]&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ParameterGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Task&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Using&lt;/span&gt; &lt;span class="attr"&gt;Namespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.IO&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Using&lt;/span&gt; &lt;span class="attr"&gt;Namespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;System.Text.RegularExpressions&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Using&lt;/span&gt; &lt;span class="attr"&gt;Namespace&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Microsoft.Build.Framework&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Code&lt;/span&gt; &lt;span class="attr"&gt;Type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Fragment&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Language&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;cs&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;                &lt;span class="kwrd"&gt;&amp;lt;!&lt;/span&gt;[CDATA[&lt;/pre&gt;

  &lt;pre class="alt"&gt;            foreach(ITaskItem item in Items) {&lt;/pre&gt;

  &lt;pre&gt;              string fileName = item.GetMetadata(&amp;quot;FullPath&amp;quot;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;              string find = item.GetMetadata(&amp;quot;Find&amp;quot;);&lt;/pre&gt;

  &lt;pre&gt;              string replaceWith = item.GetMetadata(&amp;quot;ReplaceWith&amp;quot;);&lt;/pre&gt;

  &lt;pre class="alt"&gt;              &lt;/pre&gt;

  &lt;pre&gt;              if(!File.Exists(fileName)) {&lt;/pre&gt;

  &lt;pre class="alt"&gt;                Log.LogError(null, null, null, null, 0, 0, 0, 0, String.Format(&amp;quot;Could not find version file: {0}&amp;quot;, fileName), new object[0]);&lt;/pre&gt;

  &lt;pre&gt;              }&lt;/pre&gt;

  &lt;pre class="alt"&gt;              string content = File.ReadAllText(fileName);&lt;/pre&gt;

  &lt;pre&gt;              File.WriteAllText(&lt;/pre&gt;

  &lt;pre class="alt"&gt;                fileName,&lt;/pre&gt;

  &lt;pre&gt;                Regex.Replace(&lt;/pre&gt;

  &lt;pre class="alt"&gt;                  content,&lt;/pre&gt;

  &lt;pre&gt;                  find,&lt;/pre&gt;

  &lt;pre class="alt"&gt;                  replaceWith&lt;/pre&gt;

  &lt;pre&gt;                )&lt;/pre&gt;

  &lt;pre class="alt"&gt;              );&lt;/pre&gt;

  &lt;pre&gt;            }&lt;/pre&gt;

  &lt;pre class="alt"&gt;          ]]&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Code&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Task&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;UsingTask&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Project&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;If you glance at the code, you’ll see it’s really just going a Regex.Replace() on a given file, which is exactly what we need.&lt;/p&gt;

&lt;p&gt;Now we are ready to write our build file, called (by convention) Build.proj.&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;?&lt;/span&gt;&lt;span class="html"&gt;xml&lt;/span&gt; &lt;span class="attr"&gt;version&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;1.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;encoding&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;utf-8&amp;quot;&lt;/span&gt;?&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Project&lt;/span&gt; &lt;span class="attr"&gt;ToolsVersion&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;4.0&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DefaultTargets&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Go&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;xmlns&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;http://schemas.microsoft.com/developer/msbuild/2003&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Import&lt;/span&gt; &lt;span class="attr"&gt;Project&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$(MSBuildProjectDirectory)\Build.tasks&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;PropertyGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Configuration&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;'$(Configuration)' == ''&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;Debug&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Configuration&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;SolutionRoot&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;$(MSBuildProjectDirectory)&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;SolutionRoot&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;PropertyGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexTransform&lt;/span&gt; &lt;span class="attr"&gt;Include&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$(SolutionRoot)\CommonAssemblyInfo.cs&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Find&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;(?&lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;major&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;\d+)\.(?&lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;minor&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;\d+)\.\d+\.(?&lt;span class="attr"&gt;&amp;amp;lt;&lt;/span&gt;revision&lt;span class="attr"&gt;&amp;amp;gt;&lt;/span&gt;\d+)&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Find&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;ReplaceWith&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;$(BUILD_NUMBER)&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ReplaceWith&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;RegexTransform&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;ItemGroup&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Go&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DependsOnTargets&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdateAssemblyVersion; Build&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;UpdateAssemblyVersion&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Condition&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;'$(BUILD_NUMBER)' != ''&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;RegexTransform&lt;/span&gt; &lt;span class="attr"&gt;Items&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;@(RegexTransform)&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Build&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;MSBuild&lt;/span&gt; &lt;span class="attr"&gt;Projects&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;$(SolutionRoot)\BuildVersionTest.sln&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;Targets&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;Build&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Target&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&amp;#160;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;Project&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Reviewing this MSBuild file, we see that by default the “Go” target will be called, which in turn depends on “UpdateAssemblyVersion” and then “Build.”&amp;#160; We go ahead and import the Bulid.tasks file and then setup some handy properties for setting the build configuration and solution root (in this case, my build files are in the solution root, but we might want to create a Build/ directory later).&amp;#160; The rest of the file flows logically, we setup the RegexTransform to match version numbers such as &amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.1.&amp;lt;revision&amp;gt; (1.2.3.4 in our example) and replace it with a $(BUILD_NUMBER) parameter which will be supplied externally.&amp;#160; The first target, “UpdateAssemblyVersion” just runs the RegexTransform, and the second target, “Build” just runs the default MSBuild on our solution.&lt;/p&gt;

&lt;h4&gt;&lt;u&gt;Testing the MSBuild file locally&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;Now we have a build file which can replace assembly version numbers and build, so let’s setup a quick batch file to be able to build locally.&amp;#160; To do this you simply create a file called Build.cmd and have it call MSBuild on your Build.proj file.&amp;#160; I’ve added a bit more flexibility so you can specify build configuration and version number, which makes your Build.cmd look as follows:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;set config=%1&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;%config%&amp;quot;&lt;/span&gt; == &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; (&lt;/pre&gt;

  &lt;pre class="alt"&gt;   set config=debug&lt;/pre&gt;

  &lt;pre&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;set version=%2&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; &lt;span class="str"&gt;&amp;quot;%version%&amp;quot;&lt;/span&gt; == &lt;span class="str"&gt;&amp;quot;&amp;quot;&lt;/span&gt; (&lt;/pre&gt;

  &lt;pre class="alt"&gt;   set version=2.3.4.5&lt;/pre&gt;

  &lt;pre&gt;)&lt;/pre&gt;

  &lt;pre class="alt"&gt;%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild Build.proj /p:Configuration=&lt;span class="str"&gt;&amp;quot;%config%&amp;quot;&lt;/span&gt; /p:build_number=&lt;span class="str"&gt;&amp;quot;%version%&amp;quot;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;style type="text/css"&gt;


.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Now if you click on the Build.cmd file, you will get a default debug build using the version 2.3.4.5.&amp;#160; Let’s run it in a command window with the parameters set for a release build version 2.0.1.453.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_4A23E616.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_7085C961.png" width="644" height="40" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_08A933BD.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1C561D51.png" width="644" height="452" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;

&lt;p&gt;Excellent!&amp;#160; We can now run one simple command and govern the build configuration and version number of our entire solution.&amp;#160; Each DLL produced will have the same version number, making determining which version of a library you are running very simple and accurate.&lt;/p&gt;

&lt;h4&gt;&lt;u&gt;Configure the build server (TeamCity)&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;Of course you are not really going to want to run a build command manually every time, and typing in incrementing version numbers will also not be ideal.&amp;#160; A good solution is to have a computer (or set of computers) act as a build server and build your code for you, providing you a consistent environment, excellent reporting, and much more.&amp;#160; One of the most popular Build Servers is &lt;a href="http://www.jetbrains.com/teamcity/"&gt;JetBrains’ TeamCity&lt;/a&gt;, and this last section will show you the few configuration parameters to use when setting up a build using your MSBuild file created earlier.&amp;#160; If you are using a different build server, the same principals should apply.&lt;/p&gt;

&lt;p&gt;First, when setting up the project you want to specify the “Build Number Format,” often given in the form &amp;lt;major&amp;gt;.&amp;lt;minor&amp;gt;.&amp;lt;revision&amp;gt;.&amp;lt;build&amp;gt;.&amp;#160; In this case you will set major/minor manually, and optionally revision (or you can use your VCS revision number with %build.vcs.number%), and then build using the {0} wildcard.&amp;#160; Thus your build number format might look like this: 2.0.1.{0}.&amp;#160; During each build, this value will be created and passed into the $BUILD_NUMBER variable of our Build.proj file, which then uses it to decorate your assemblies with the proper version.&lt;/p&gt;

&lt;p&gt;After setting up the build number, you must choose MSBuild as the Build Runner, then provide a path to your build file (Build.proj).&amp;#160; After specifying your MSBuild Version (equivalent to your .NET Framework Version), you have the option to specify targets (the default being “Go”) and additional MSBuild parameters.&amp;#160; The one parameter that is often useful is manually setting the configuration property (/p:Configuration=&amp;quot;Release&amp;quot;) if you want something other than the default (which is Debug in our example).&amp;#160; &lt;/p&gt;

&lt;p&gt;Your resulting configuration will look something like this:&lt;/p&gt;

&lt;p&gt;[Under General Settings]&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_207FF516.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_0AB60CB9.png" width="644" height="47" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[Build Runner Settings] &lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_49A78D54.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_28B41AAD.png" width="644" height="472" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;Now every time your build is run, a newly incremented build version number will be generated and passed to MSBuild, which will then version your assemblies and build your solution.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h4&gt;&lt;u&gt;A Quick Review&lt;/u&gt;&lt;/h4&gt;

&lt;p&gt;Our goal was to version our output assemblies in an automated way, and we accomplished it by performing a few quick steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Move the common assembly information, including version, into a linked CommonAssemblyInfo.cs file &lt;/li&gt;

  &lt;li&gt;Create a simple MSBuild script to replace the common assembly version number and build your solution &lt;/li&gt;

  &lt;li&gt;Direct your build server to use the created MSBuild script &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s really all there is to it.&amp;#160; You can find all of the code from this post at &lt;a title="https://github.com/srkirkland/BuildVersion" href="https://github.com/srkirkland/BuildVersion"&gt;https://github.com/srkirkland/BuildVersion&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7657799" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/TFS/default.aspx">TFS</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MSBuild/default.aspx">MSBuild</category></item><item><title>jQuery Overview Presentation</title><link>http://weblogs.asp.net/srkirkland/archive/2010/09/27/jquery-overview-presentation.aspx</link><pubDate>Mon, 27 Sep 2010 16:39:13 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7620936</guid><dc:creator>srkirkland</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7620936</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2010/09/27/jquery-overview-presentation.aspx#comments</comments><description>&lt;p&gt;Last week I gave a presentation to the UC.NET User Group which provided an overview/introduction to jQuery.&amp;#160; Instead of using PowerPoint I created an ASP.NET MVC website and used a jQuery presentation plugin (&lt;a title="http://www.viget.com/inspire/jquery-presentation-plugin/" href="http://www.viget.com/inspire/jquery-presentation-plugin/"&gt;http://www.viget.com/inspire/jquery-presentation-plugin/&lt;/a&gt;) to provide slide navigation and animation, which allowed me to make the presentation very interactive.&lt;/p&gt;  &lt;p&gt;The presentation was well received so I thought I’d make the full source code, as well as a live version of the final presentation, publicly available for anyone who is interested.&lt;/p&gt;  &lt;p&gt;Full Source Code: &lt;a title="http://github.com/srkirkland/jQueryPresentation" href="http://github.com/srkirkland/jQueryPresentation"&gt;http://github.com/srkirkland/jQueryPresentation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Live Presentation: &lt;a title="https://test.caes.ucdavis.edu/jQueryPresentation" href="https://test.caes.ucdavis.edu/jQueryPresentation"&gt;https://test.caes.ucdavis.edu/jQueryPresentation&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Enjoy!&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;[Example Slides]&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_6D7491A0.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1F8BBC1E.png" width="562" height="320" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2421C6D8.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_68EDEB0C.png" width="561" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_601DE2C0.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_7CD757D5.png" width="569" height="364" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7620936" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/jQuery/default.aspx">jQuery</category></item><item><title>NHibernate Client Validator ASP.NET MVC 2 Model Validation</title><link>http://weblogs.asp.net/srkirkland/archive/2010/07/20/nhibernate-client-validator-asp-net-mvc-2-model-validation.aspx</link><pubDate>Tue, 20 Jul 2010 20:17:57 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7570351</guid><dc:creator>srkirkland</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7570351</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2010/07/20/nhibernate-client-validator-asp-net-mvc-2-model-validation.aspx#comments</comments><description>&lt;p&gt;ASP.NET MVC 2 improves Model Validation in a number of ways, including the addition of client side validation (ala xVal).&amp;#160; If you would like more information on Model Validation in ASP.NET MVC 2, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx"&gt;Scott Gu’s detailed post on this subject&lt;/a&gt;.&amp;#160; Out of the box ASP.NET MVC 2 includes support for DataAnnotations, and there are some extensibility points available for plugging in your own framework.&lt;/p&gt;  &lt;p&gt;In post series I am creating my own implementations of Model Validation using NHibernate Validator (aka NHV, part of &lt;a href="http://sourceforge.net/projects/nhcontrib/files/"&gt;NHibernate Contrib&lt;/a&gt;).&amp;#160; This post will focus on the client-side model validation – you can find the &lt;a href="http://weblogs.asp.net/srkirkland/archive/2010/03/02/nhibernate-validator-asp-net-mvc-2-model-validation.aspx" target="_blank"&gt;previous post covering server-side validation here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Note:&amp;#160; If you just want to see the final code, including a sample project, go to &lt;a title="http://github.com/srkirkland/NHValModelValidators" href="http://github.com/srkirkland/NHValModelValidators"&gt;http://github.com/srkirkland/NHValModelValidators&lt;/a&gt;.&lt;/p&gt;  &lt;h5&gt;&lt;u&gt;The Setup – Validating Customers&lt;/u&gt;&lt;/h5&gt;  &lt;p&gt;Below is the simple Customer class which we will use for validation.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Customer : BaseObject&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [Length(10)]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; CompanyName { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [NotNullNotEmpty(Message = &lt;span style="color: #006080"&gt;&amp;quot;Don't forget the contact name&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ContactName { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Country { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [Pattern(&lt;span style="color: #006080"&gt;&amp;quot;^[0-9]{6}&amp;quot;&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Fax { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    [Range(1, 200)]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;virtual&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So we are using some NotNullNotEmpty validators, a String Length validator, a Range and a Regular Expression Pattern validator for testing.&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;&lt;/u&gt;&lt;/h5&gt;

&lt;h5&gt;&lt;u&gt;More Setup – Getting the Validator Engine&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;Eventually we will need to get the validation engine in order to interact with the NHibernate Validator library, and everyone probably has a different way of getting their configured engine.&amp;#160; For these examples (and simplicity’s sake) I’m going to use the following engine factory:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ValidatorEngineFactory&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ValidatorEngine ValidatorEngine&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        get&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (NHibernate.Validator.Cfg.Environment.SharedEngineProvider == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                NHibernate.Validator.Cfg.Environment.SharedEngineProvider = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NHibernateSharedEngineProvider();&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Setting up the ModelValidatorProvider&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;The first step towards hooking up Model Validation is to create a class which inherits from System.Web.Mvc.ModelValidatorProvider.&amp;#160; For added convenience and utility I am going to inherit from&amp;#160; System.Web.Mvc.AssociatedValidatorProvider, which is a helper class provided by MVC to find associated information from your validatable fields (in our case, we want the associated validation attributes).&amp;#160; This class has one method you need to override, which is:&amp;#160; &lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelValidator&amp;gt; GetValidators(&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            ModelMetadata metadata, &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            ControllerContext context, &lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            IEnumerable&amp;lt;Attribute&amp;gt; attributes&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        )&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;What we want to do with this provider is to return a list of ModelValidators that know which ModelClientValidationRule instances are associated with the given property.&amp;#160; Hopefully this will all become clear over the reminder of this article.&lt;/p&gt;

&lt;p&gt;Since we are doing client-side validation and want to utilize the exiting ASP.NET MVC2 client-size validation rules then we need a way to map the NHibernate Validator constraints to MVC2 System.Web.Mvc.ModelClientValidationRule instances.&amp;#160; First we will create a class to help us with the mapping:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; RuleEmitterList&amp;lt;TInputBase&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;delegate&lt;/span&gt; IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; RuleEmitter(TInputBase item);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; List&amp;lt;RuleEmitter&amp;gt; _ruleEmitters = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;RuleEmitter&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddSingle&amp;lt;TSource&amp;gt;(Func&amp;lt;TSource, ModelClientValidationRule&amp;gt; emitter) &lt;span style="color: #0000ff"&gt;where&lt;/span&gt; TSource : TInputBase&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.Add(x =&amp;gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                              {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (x &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; TSource)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                      ModelClientValidationRule rule = emitter((TSource)x);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; rule == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; ? &lt;span style="color: #0000ff"&gt;null&lt;/span&gt; : &lt;span style="color: #0000ff"&gt;new&lt;/span&gt;[] { rule };&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                      &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                                  }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                              });&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; EmitRules(TInputBase item)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var emitter &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _ruleEmitters)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var emitterResult = emitter(item);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (emitterResult != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; emitterResult;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRule[] { }; &lt;span style="color: #008000"&gt;//No matching emitter, so return an empty set of rules&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This RuleEmitterList will take a type and “convert” that type into ModelClientValidationRules.&amp;#160; This technique is similar to how xVal solved a related problem.&amp;#160; You will see how this is used in just a minute.&lt;/p&gt;

&lt;p&gt;In the constructor (which is run only once) we do the mapping:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; NHibernateValidatorClientProvider : AssociatedValidatorProvider&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; RuleEmitterList&amp;lt;IRuleArgs&amp;gt; _ruleEmitters;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// ctor: Hook up the mappings between your attributes and model client validation rules&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; NHibernateValidatorClientProvider()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RuleEmitterList&amp;lt;IRuleArgs&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;NotNullNotEmptyAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRequiredRule(x.Message));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;NotEmptyAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRequiredRule(x.Message));&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;NotNullAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRequiredRule(x.Message));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;LengthAttribute&amp;gt;(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationStringLengthRule(x.Message, x.Min, x.Max));&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;MinAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRangeRule(x.Message, x.Value, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;));&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;MaxAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRangeRule(x.Message, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, x.Value));&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;NHibernate.Validator.Constraints.RangeAttribute&amp;gt;(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRangeRule(x.Message, x.Min, x.Max));&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        _ruleEmitters.AddSingle&amp;lt;PatternAttribute&amp;gt;(x =&amp;gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ModelClientValidationRegexRule(x.Message, x.Regex));&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So here we decided to map IRuleArgs (an NHibernate Validator interface) to their related MVC2 ModelClientValidator*Rule instances.&amp;#160; NonNullNotEmptyAttribute, for instance, is really a RequiredRule. Getting slightly more complex, a MaxAttribute is really a MVC2 RangeRule with the min value set to null.&amp;#160; All NHibernate Validator attributes that are not mapped will be ignored.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Implementing the ModelValidatorProvider&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;So now that we have our rules mapped, we have to do the actual work of inspecting our properties and emitting rules.&amp;#160; To do this we will basically use the NHibernate Validator library to get the constraints for every “property” and then convert our constraints to the desired rules.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// Returns the validators for the given class metadata.  This gets called for each property.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;Yield returns client validator instances with a list of rules for the current property&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelValidator&amp;gt; GetValidators(&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ModelMetadata metadata, &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ControllerContext context, &lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    IEnumerable&amp;lt;Attribute&amp;gt; attributes&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (metadata.ContainerType == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;; &lt;span style="color: #008000"&gt;//Break if there is no metadata container&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    var engine = ValidatorEngineFactory.ValidatorEngine;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    var validator = engine.GetClassValidator(metadata.ContainerType);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    var constraints = validator.GetMemberConstraints(metadata.PropertyName).OfType&amp;lt;IRuleArgs&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    var rules = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;ModelClientValidationRule&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var constraint &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; constraints) &lt;span style="color: #008000"&gt;//for each constraint, emit the rules for that constraint&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (var validationRule &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; _ruleEmitters.EmitRules(constraint))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            validationRule.ErrorMessage = constraint.Message; &lt;span style="color: #008000"&gt;//Temporarily give validation rule the error message provided by the validator&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            validationRule.ErrorMessage = MessageOrDefault(validationRule, metadata.PropertyName); &lt;span style="color: #008000"&gt;//Get a true error message if not provided&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            rules.Add(validationRule);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;yield&lt;/span&gt; &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NHibernateValidatorClientValidator(metadata, context, rules);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;There is nothing too crazy here, but we do have to be aware that one property can have many constraints, and for each constraint we must emit the proper rule (using our ruleEmitters mapping).&amp;#160; Then for each validation rule we must get the proper error message (described later) and add it to our list of rules for that property.&amp;#160; Then we yield return a simple ModelValidator instance (called NHibernateValidatorClientValidator) which just a dumb container for presenting the rules we provided.&amp;#160; Let’s take a look at it:&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Implementing The Simple ModelValidator&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;As mentioned above, our model validator is pretty simple since our provider did all of the work.&amp;#160; We store the list of ModelClientValidationRule classes that was passed in to the constructor and override the GetClientValidationRules method to return this list.&amp;#160; We are forced to override the Validate method as well, but here we just return an empty list since we aren’t concerned about server-size validation here.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// Simple validator class which overrides GetClientValidationRules to return a list of ModelClientValidationRules, which cause client side validation&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; NHibernateValidatorClientValidator : ModelValidator&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; NHibernateValidatorClientValidator(ModelMetadata metadata, ControllerContext controllerContext, List&amp;lt;ModelClientValidationRule&amp;gt; rules)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        : &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;(metadata, controllerContext)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        Rules = rules;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; List&amp;lt;ModelClientValidationRule&amp;gt; Rules { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// Simply returns the supplied list of ModelClientValidationRule instances.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelClientValidationRule&amp;gt; GetClientValidationRules()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Rules;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// Returns an empty enumeration since this is not a server-side validator&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelValidationResult&amp;gt; Validate(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; container)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Enumerable.Empty&amp;lt;ModelValidationResult&amp;gt;();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Getting Good Error Messages&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;One tricky aspect of client validation is that NHV creates messages at runtime, so there isn’t a static message that can be displayed in advance.&amp;#160; If you provide NHibernate with a static message using the Message = ‘msg’ parameter then we can display that easily, but if no message is provided then we have to go another route.&amp;#160; So what I decided to do was workaround this by having the built-in System.ComponentModel.DataAnnotations validators provide the messages for me (of course, they rely on a static resource file under the covers, but it is internal and not directly accessible).&lt;/p&gt;

&lt;p&gt;Our strategy will be to inspect the rule we have to see if the error message was provided.&amp;#160; If is was not provided, we will inspect the validation rule to and determine its type.&amp;#160; Using this type we will create a new instance of the corresponding DataAnnotations validator and use the message it provides.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; MessageOrDefault(ModelClientValidationRule rule, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; propertyName)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;// We don't want to display the default {validator.*} messages&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((rule.ErrorMessage != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; !rule.ErrorMessage.StartsWith(&lt;span style="color: #006080"&gt;&amp;quot;{validator.&amp;quot;&lt;/span&gt;))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; rule.ErrorMessage;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (rule.ValidationType)&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;stringLength&amp;quot;&lt;/span&gt; :&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var maxLength = (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;) rule.ValidationParameters[&lt;span style="color: #006080"&gt;&amp;quot;maximumLength&amp;quot;&lt;/span&gt;];&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; StringLengthAttribute(maxLength).FormatErrorMessage(propertyName);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;required&amp;quot;&lt;/span&gt; :&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RequiredAttribute().FormatErrorMessage(propertyName);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;range&amp;quot;&lt;/span&gt; :&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var min = Convert.ToDouble(rule.ValidationParameters[&lt;span style="color: #006080"&gt;&amp;quot;minimum&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var max = Convert.ToDouble(rule.ValidationParameters[&lt;span style="color: #006080"&gt;&amp;quot;maximum&amp;quot;&lt;/span&gt;]);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; System.ComponentModel.DataAnnotations.RangeAttribute(min, max).FormatErrorMessage(propertyName);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; &lt;span style="color: #006080"&gt;&amp;quot;regularExpression&amp;quot;&lt;/span&gt;:&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var pattern = (&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;)rule.ValidationParameters[&lt;span style="color: #006080"&gt;&amp;quot;pattern&amp;quot;&lt;/span&gt;];&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RegularExpressionAttribute(pattern).FormatErrorMessage(propertyName);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;default&lt;/span&gt;:&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NotSupportedException(&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;                &lt;span style="color: #006080"&gt;&amp;quot;Only stringLength, Required, Range and RegularExpression validators are supported for generic error messages.  Add a custom error message or choose another validator type&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }   &lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Hooking up the Client-Side ModelValidatorProvider&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;Now we have our new ModelValidationProvider but we still have to register it in the global.asax file:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Application_Start()&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    AreaRegistration.RegisterAllAreas();&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    RegisterRoutes(RouteTable.Routes);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ModelValidatorProviders.Providers.Clear(); &lt;span style="color: #008000"&gt;//Optional: Remove the default data annotations validations&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ModelValidatorProviders.Providers.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NHibernateValidatorProvider()); &lt;span style="color: #008000"&gt;//Server side validation provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    ModelValidatorProviders.Providers.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; NHibernateValidatorClientProvider()); &lt;span style="color: #008000"&gt;//Client side validation provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The last line here is where we add our new client side NHibernateValidatorClientProvider.&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Results – Validation In Action&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;Here is a quick action/view which should test many of the validators we configured above:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_4E2E2211.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_0D1FA2AD.png" width="405" height="307" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_1E23D090.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_1221E05C.png" width="338" height="430" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;To show there is no magic here I used the awesome Html.EditorForModel() helper to create the form (the model was our Customer class shown at the top of this post).&amp;#160; The other important line is &amp;lt;% Html.EnableClientValidation(); %&amp;gt;, which tells ASP.NET MVC 2 to emit its client validation scripts (note: you’ll have to reference the proper javascript files – I used MicrosoftAjax.js and MicrosoftMvcValidaton.js).&lt;/p&gt;

&lt;p&gt;Now let’s try to create the Customer and see what happens:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_7C57F7FE.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_575A3785.png" width="568" height="427" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As expected, we fail validation and get pretty good error messages.&amp;#160; Note the “Don’t forget the contact name” custom message got through properly.&lt;/p&gt;

&lt;p&gt;Let’s try typing into the company name box without hitting submit and see what happens:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_41904F28.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_404BB649.png" width="739" height="429" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Excellent!&amp;#160; So now we have fully integrated client and server side validation with ASP.NET MVC.&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;h5&gt;&lt;u&gt;Show Me Code Or It Didn’t Happen&lt;/u&gt;&lt;/h5&gt;

&lt;p&gt;All of the code needed to get server and client side validation integrated with ASP.NET MVC 2, along with a sample project, can be found at &lt;a title="http://github.com/srkirkland/NHValModelValidators" href="http://github.com/srkirkland/NHValModelValidators"&gt;http://github.com/srkirkland/NHValModelValidators&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7570351" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category></item><item><title>Guarding against CSRF Attacks in ASP.NET MVC2</title><link>http://weblogs.asp.net/srkirkland/archive/2010/04/14/guarding-against-csrf-attacks-in-asp-net-mvc2.aspx</link><pubDate>Wed, 14 Apr 2010 17:50:18 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7444051</guid><dc:creator>srkirkland</dc:creator><slash:comments>21</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7444051</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2010/04/14/guarding-against-csrf-attacks-in-asp-net-mvc2.aspx#comments</comments><description>&lt;p&gt;Alongside XSS (Cross Site Scripting) and SQL Injection, &lt;b&gt;Cross-site Request Forgery (CSRF)&lt;/b&gt; attacks represent the three most common and dangerous vulnerabilities to common web applications today. CSRF attacks are probably the least well known but they are relatively easy to exploit and extremely and increasingly dangerous. For more information on CSRF attacks, see these posts by &lt;img title="external link" alt="external link: " src="https://smartsite.ucdavis.edu/sakai-rwiki-tool/images/icklearrow.gif" /&gt;&lt;a href="http://haacked.com/archive/2009/04/02/anatomy-of-csrf-attack.aspx"&gt;Phil Haack&lt;/a&gt; and &lt;img title="external link" alt="external link: " src="https://smartsite.ucdavis.edu/sakai-rwiki-tool/images/icklearrow.gif" /&gt;&lt;a href="http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-%20aspnet-mvcs-antiforgerytoken-helper/"&gt;Steve Sanderson&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The recognized solution for preventing CSRF attacks is to put a user-specific token as a hidden field inside your forms, then check that the right value was submitted. It's best to use a random value which you’ve stored in the visitor’s Session collection or into a Cookie (so an attacker can't guess the value). &lt;/p&gt;  &lt;h3&gt;&lt;u&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;u&gt;&lt;strong&gt;ASP.NET MVC to the rescue&lt;/strong&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;ASP.NET MVC provides an HTMLHelper called AntiForgeryToken(). When you call &amp;lt;%= Html.AntiForgeryToken() %&amp;gt; in a form on your page you will get a hidden input and a Cookie with a random string assigned.&lt;/p&gt;  &lt;p&gt;Next, on your target Action you need to include [ValidateAntiForgeryToken], which handles the verification that the correct token was supplied. &lt;/p&gt;  &lt;h3&gt;&lt;u&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;u&gt;&lt;strong&gt;Good, but we can do better&lt;/strong&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Using the AntiForgeryToken is actually quite an elegant solution, but adding [ValidateAntiForgeryToken] on all of your POST methods is not very DRY, and worse can be easily forgotten.&lt;/p&gt;  &lt;p&gt;Let's see if we can make this easier on the program but moving from an &amp;quot;Opt-In&amp;quot; model of protection to an &amp;quot;Opt-Out&amp;quot; model. &lt;/p&gt;  &lt;h3&gt;&lt;u&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;h3&gt;&lt;u&gt;&lt;strong&gt;Using AntiForgeryToken by default&lt;/strong&gt;&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;In order to mandate the use of the AntiForgeryToken, we're going to create an ActionFilterAttribute which will do the anti-forgery validation on every POST request.&lt;/p&gt;  &lt;p&gt;First, we need to create a way to Opt-Out of this behavior, so let's create a quick action filter called BypassAntiForgeryToken:&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[AttributeUsage(AttributeTargets.Method, AllowMultiple=&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; BypassAntiForgeryTokenAttribute : ActionFilterAttribute { }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now we are ready to implement the main action filter which will force anti forgery validation on all post actions within any class it is defined on:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[AttributeUsage(AttributeTargets.Class, AllowMultiple = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; UseAntiForgeryTokenOnPostByDefault : ActionFilterAttribute&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnActionExecuting(ActionExecutingContext filterContext)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ShouldValidateAntiForgeryTokenManually(filterContext))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            var authorizationContext = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; AuthorizationContext(filterContext.Controller.ControllerContext);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #008000"&gt;//Use the authorization of the anti forgery token, &lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #008000"&gt;//which can't be inhereted from because it is sealed&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;            &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ValidateAntiForgeryTokenAttribute().OnAuthorization(authorizationContext);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;base&lt;/span&gt;.OnActionExecuting(filterContext);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// We should validate the anti forgery token manually if the following criteria are met:&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// 1. The http method must be POST&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// 2. There is not an existing [ValidateAntiForgeryToken] attribute on the action&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// 3. There is no [BypassAntiForgeryToken] attribute on the action&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; ShouldValidateAntiForgeryTokenManually(ActionExecutingContext filterContext)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        var httpMethod = filterContext.HttpContext.Request.HttpMethod;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;//1. The http method must be POST&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (httpMethod != &lt;span style="color: #006080"&gt;&amp;quot;POST&amp;quot;&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// 2. There is not an existing anti forgery token attribute on the action&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        var antiForgeryAttributes = filterContext.ActionDescriptor.GetCustomAttributes(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(ValidateAntiForgeryTokenAttribute), &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (antiForgeryAttributes.Length &amp;gt; 0) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #008000"&gt;// 3. There is no [BypassAntiForgeryToken] attribute on the action&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        var ignoreAntiForgeryAttributes = filterContext.ActionDescriptor.GetCustomAttributes(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(BypassAntiForgeryTokenAttribute), &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ignoreAntiForgeryAttributes.Length &amp;gt; 0) &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The code above is pretty straight forward -- first we check to make sure this is a POST request, then we make sure there aren't any overriding *AntiForgeryTokenAttributes on the action being executed. If we have a candidate then we call the ValidateAntiForgeryTokenAttribute class directly and execute OnAuthorization() on the current authorization context.&lt;/p&gt;

&lt;p&gt;Now on our base controller, you could use this new attribute to start protecting your site from CSRF vulnerabilities.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;[UseAntiForgeryTokenOnPostByDefault]&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ApplicationController : System.Web.Mvc.Controller { }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&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: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;//Then for all of your controllers&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HomeController : ApplicationController {}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
  &lt;strong&gt;&lt;u&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/div&gt;

&lt;h3&gt;&lt;strong&gt;&lt;u&gt;&lt;/u&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;h3&gt;&lt;strong&gt;&lt;u&gt;What we accomplished&lt;/u&gt;&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;If your base controller has the new default anti-forgery token attribute on it, when you don't use &amp;lt;%= Html.AntiForgeryToken() %&amp;gt; in a form (or of course when an attacker doesn't supply one), the POST action will throw the descriptive error message &amp;quot;A required anti-forgery token was not supplied or was invalid&amp;quot;. Attack foiled!&lt;/p&gt;

&lt;p&gt;In summary, I think having an anti-CSRF policy by default is an effective way to protect your websites, and it turns out it is pretty easy to accomplish as well.&lt;/p&gt;

&lt;p&gt;Enjoy! &lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7444051" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category></item><item><title>NHibernate Validator ASP.NET MVC 2 Model Validation</title><link>http://weblogs.asp.net/srkirkland/archive/2010/03/02/nhibernate-validator-asp-net-mvc-2-model-validation.aspx</link><pubDate>Tue, 02 Mar 2010 21:42:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:7368110</guid><dc:creator>srkirkland</dc:creator><slash:comments>14</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/srkirkland/rsscomments.aspx?PostID=7368110</wfw:commentRss><comments>http://weblogs.asp.net/srkirkland/archive/2010/03/02/nhibernate-validator-asp-net-mvc-2-model-validation.aspx#comments</comments><description>&lt;p&gt;ASP.NET MVC2 will improve the built in Model Validation in a number of ways, including the addition of client side validation (ala xVal).&amp;nbsp; If you would like more information on Model Validation in ASP.NET MVC 2, see &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx" target="_blank"&gt;Scott Gu’s detailed post on this subject&lt;/a&gt;.&amp;nbsp; Out of the box ASP.NET MVC 2 will include support for DataAnnotations, and there are some extensibility points available for plugging in your own framework.&lt;/p&gt;  &lt;p&gt;In post series I am going to create a Model Validator using NHibernate Validator (part of &lt;a href="http://sourceforge.net/projects/nhcontrib/files/" mce_href="http://sourceforge.net/projects/nhcontrib/files/" target="_blank"&gt;NHibernate Contrib&lt;/a&gt;).&amp;nbsp; This post will focus on the server-side model validation, and the next post will hopefully focus on adding client-side model validation.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;/p&gt;  &lt;h3&gt;&lt;u&gt;The Setup – Validating Customers&lt;/u&gt;&lt;/h3&gt;  &lt;p&gt;Below is an example of our Customer class which we will use for validation.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;     &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Customer : BaseObject&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [Length(10)]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; CompanyName { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; ContactName { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; Country { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [NotNullNotEmpty]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; Fax { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    [Range(1, 200, &lt;span style="color: rgb(0, 96, 128);"&gt;"Must be between 1 and 200"&lt;/span&gt;)]&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; Age { get; set; }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So we are using some NotNullNotEmpty validators, a String Length validator, and a Range validator for testing.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;More Setup – Getting the Validator Engine&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Eventually we will need to get the validation engine in order to interact with the NHibernate Validator library, and everyone probably has a different way of getting their configured engine.&amp;nbsp; For these examples (and simplicity’s sake) I’m going to use the following engine factory:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;
    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; ValidatorEngineFactory&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; ValidatorEngine ValidatorEngine&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        get&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (NHibernate.Validator.Cfg.Environment.SharedEngineProvider == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;                NHibernate.Validator.Cfg.Environment.SharedEngineProvider = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; NHibernateSharedEngineProvider();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; NHibernate.Validator.Cfg.Environment.SharedEngineProvider.GetEngine();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Implementing a ModelValidatorProvider&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;The first step towards hooking up Model Validation is to create a class which inherits from System.Web.Mvc.ModelValidatorProvider.&amp;nbsp; This class has one method you need to override, which is:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;
    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;IEnumerable&amp;lt;ModelValidator&amp;gt; GetValidators(ModelMetadata metadata, ControllerContext context)&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Note: GetValidators gets called for all of the properties of your model, so be prepared to have this method called multiple times.&lt;/p&gt;

&lt;p&gt;For our implementation, we will grab the validator engine, then attempt to get the ClassValidator for the current Model Type.&amp;nbsp; The Model Type will be different every time GetValidators() is called, so we wait until we have the full class validator (classValidator != null) before returning anything.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;
    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Server side validator provider for NHVal&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; NHibernateValidatorProvider : ModelValidatorProvider&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// Returns model validators for each class that can be validated.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// When this method is called with a non-class modelType, nothing is added to the yield return&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// (this prevents us from validating the same properties several times)&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelValidator&amp;gt; GetValidators(ModelMetadata metadata, ControllerContext context)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        var validationEngine = ValidatorEngineFactory.ValidatorEngine;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        var classValidator = validationEngine.GetClassValidator(metadata.ModelType);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (classValidator != &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; NHibernateValidatorModelValidator(metadata, context, classValidator);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;What we are yield returning here (in the case we have a classValidator) is an instance of a new subclass of ModelValidator, which is given the classValidator and will handle the actual validation when called upon by the framework.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Implementing a ModelValidator&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Now we need to create a class which inherits from ModelValidator, which will do the actual validation (utilizing the classValidator previously passed in).&amp;nbsp; I’ll show the final code first, and then explain it:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;
    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Server side model validator for NHVal&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; NHibernateValidatorModelValidator : ModelValidator&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;readonly&lt;/span&gt; IClassValidator _validator;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; NHibernateValidatorModelValidator(ModelMetadata metadata, ControllerContext controllerContext, IClassValidator validator)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        : &lt;span style="color: rgb(0, 0, 255);"&gt;base&lt;/span&gt;(metadata, controllerContext)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        _validator = validator;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// Validate the model associated with this validator&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; IEnumerable&amp;lt;ModelValidationResult&amp;gt; Validate(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; container)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        var validationResults = _validator.GetInvalidValues(Metadata.Model);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (var validationResult &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; validationResults)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;yield&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;                &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ModelValidationResult { MemberName = validationResult.PropertyName, Message = validationResult.Message };&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;        }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;First we create a constructor which takes an IClassValidator, as well as the metadata and controllerContext (which we pass to the base ctor).&amp;nbsp; Here we just save a local instance of the validator for use later.&amp;nbsp; Eventually the framework will call Validate(), which is abstract and must be overridden.&amp;nbsp; There is also a method you can override called GetClientValidationRules(), but since we are concerned only about server-side for now, we’ll leave that for next time.&lt;/p&gt;

&lt;p&gt;The Validate method is pretty simple—basically we grab the invalid values for the Model and transform each result into a ModelValidationResult and yield return it.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Hooking up the ModelValidatorProvider&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;Now we have a ModelValidatorProvider but ASP.NET MVC knows nothing about it, so we go to the global.asax file and register this new provider:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;div style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;" id="codeSnippet"&gt;
    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Application_Start()&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    AreaRegistration.RegisterAllAreas();&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    RegisterRoutes(RouteTable.Routes);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    ModelValidatorProviders.Providers.Clear(); &lt;span style="color: rgb(0, 128, 0);"&gt;//Optional: Remove the default data annotations validations&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;&amp;nbsp;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: white; margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;    ModelValidatorProviders.Providers.Add(&lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; NHibernateValidatorProvider()); &lt;span style="color: rgb(0, 128, 0);"&gt;//Server side validation provider&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-style: none; text-align: left; padding: 0px; line-height: 12pt; background-color: rgb(244, 244, 244); margin: 0em; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt; overflow: visible;"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The last line here is the most important – it is where you add the NHibernateValidatorProvider to ASP.NET MVC’s ValidatorProviders collection.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;Results – Validation In Action&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;I made a quick Create action/view according to the built-in templates, which looks a little like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_18CFB538.png" mce_href="http://weblogs.asp.net/blogs/srkirkland/image_18CFB538.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_5C37B69A.png" style="border: 0px none; display: inline;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_5C37B69A.png" width="632" border="0" height="423"&gt;&lt;/a&gt; &lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_2967B026.png" mce_href="http://weblogs.asp.net/blogs/srkirkland/image_2967B026.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_56E8CFE9.png" style="border: 0px none; display: inline;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_56E8CFE9.png" width="300" border="0" height="399"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;There is more markup, but the point is there is no validation code in here and it is really just using defaults.&lt;/p&gt;

&lt;p&gt;Now, let’s try to create the Customer and see what happens:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/srkirkland/image_36619037.png" mce_href="http://weblogs.asp.net/blogs/srkirkland/image_36619037.png"&gt;&lt;img src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_39FFAB14.png" style="border: 0px none; display: inline;" title="image" alt="image" mce_src="http://weblogs.asp.net/blogs/srkirkland/image_thumb_39FFAB14.png" width="492" border="0" height="404"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Just as expected, we fail validation according to the NHibernate Validator Attributes we setup at the beginning of the post.&amp;nbsp; Notice this is all completely integrated with ASP.NET MVC – there is no validation calls in the controller or the view.&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h3&gt;&lt;u&gt;The Future, Conan?&lt;/u&gt;&lt;/h3&gt;

&lt;p&gt;I’m really happy how this turned out, but of course server-side validation is only part of the story (though an invaluable part).&amp;nbsp; Part 2 of the series will deal with creating a client-side ModelValidationProvider.&lt;/p&gt;

&lt;p&gt;The code above is basically all you need to get server-side validation integrated with ASP.NET MVC 2, though the entire source (including a sample project) can be found at &lt;a href="http://github.com/srkirkland/NHValModelValidators" title="http://github.com/srkirkland/NHValModelValidators" mce_href="http://github.com/srkirkland/NHValModelValidators"&gt;http://github.com/srkirkland/NHValModelValidators&lt;/a&gt;.&amp;nbsp; &lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7368110" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Code/default.aspx">Code</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/Validation/default.aspx">Validation</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/NHibernate/default.aspx">NHibernate</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category><category domain="http://weblogs.asp.net/srkirkland/archive/tags/MVC/default.aspx">MVC</category></item></channel></rss>