<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Enterprise Library</title>
        <link>http://geekswithblogs.net/michelotti/category/8249.aspx</link>
        <description>Enterprise Library</description>
        <language>en-US</language>
        <copyright>Steve Michelotti</copyright>
        <managingEditor>steve.michelotti@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>FredNUG Code Samples</title>
            <link>http://geekswithblogs.net/michelotti/archive/2009/08/27/frednug-code-samples.aspx</link>
            <description>Thanks to everyone who attended my presentation last night at &lt;a href="http://frednug.org/"&gt;FredNUG&lt;/a&gt;.  The code samples can be downloaded &lt;a href="http://code.msdn.microsoft.com/Release/ProjectReleases.aspx?ProjectName=michelotti&amp;amp;ReleaseId=938"&gt;here&lt;/a&gt;.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=134356"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=134356" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/134356.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2009/08/27/frednug-code-samples.aspx</guid>
            <pubDate>Thu, 27 Aug 2009 16:30:28 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/134356.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/08/27/frednug-code-samples.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/134356.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/134356.aspx</trackback:ping>
        </item>
        <item>
            <title>Enterprise Library Validation Application Block with MVC Binders</title>
            <link>http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx</link>
            <description>&lt;p&gt;A while back, I blogged about using the &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx" target="_blank"&gt;Enterprise Library Validation Application Block (VAB) with ASP.NET MVC&lt;/a&gt;. As MVC has matured as a framework, this scenario has becoming simpler.  In early releases of MVC, I implemented the execution of the VAB validation in the controller methods.  However, I now prefer to put that logic in the binders themselves.  In earlier versions of the framework, the model binders that came out of the box dealt well with simple objects but if you had more complex View Models (&lt;a href="http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx" target="_blank"&gt;as described in this post&lt;/a&gt;) then you had to roll your own binder.  With the latest releases of MVC, the DefaultModelBinder that comes OOTB with MVC is now quite robust and is even capable of dealing with those more complex binding scenarios.  Hence, my preferred method for performing the valiation is best described in &lt;a href="http://codebetter.com/blogs/david.hayden/archive/2009/02/03/an-aha-moment-on-mvc-validation-extensibility-in-defaultmodelbinder-bye-to-idataerrorinfo.aspx" target="_blank"&gt;this post by David Hayden here&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;However, the one issue with that method is that, although the binder deals well with the complex object, you’ll still run into the same issue with the VAB when it comes to the Key property of the validation messages.  That is, the key is the name of the business object property itself which does not always match the property of the view model.  For example, let’s revisit the example from my previous post and update it to use this new method.  We have our Model passed to our view defined as:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ContactViewData&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; Contact Contact { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; IEnumerable&amp;lt;State&amp;gt; StateList { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;We bind to our textbox like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Or, if you prefer the MVC Futures approach, like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBoxFor(m =&amp;gt; m.Contact.FirstName) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;So our mismatch is that when the FirstName is invalid, the key for the validation result will be “FirstName” but we were binding to “Contact.FirstName”.  You have two basic options to tackle this type of situation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Option 1 – Prepend appropriate prefix with your binder&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is basically a re-write of my original method by utilizing a custom model binder that derives from the DefaultModelBinder.  This is also a hybrid of Hayden’s approach:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; ContactModelBinder : DefaultModelBinder&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        var validator = ValidationFactory.CreateValidator(bindingContext.ModelType);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        var validationResults = validator.Validate(bindingContext.Model);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var result &lt;span class="kwrd"&gt;in&lt;/span&gt; validationResults)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            &lt;span class="kwrd"&gt;string&lt;/span&gt; mvcKey = GetMvcKey(result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            bindingContext.ModelState.AddModelError(mvcKey, result.Message);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; propertyPrefixMap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Contact), &lt;span class="str"&gt;"Contact"&lt;/span&gt; },&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Address), &lt;span class="str"&gt;"Contact.Address"&lt;/span&gt; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    };&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;    &lt;span class="rem"&gt;/// Converts an Enterprise Library ValidationResult into the correct "key" to be used by MVC Views.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="validationResult"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetMvcKey(ValidationResult validationResult)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; result;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        propertyPrefixMap.TryGetValue(validationResult.Target.GetType(), &lt;span class="kwrd"&gt;out&lt;/span&gt; result);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(result))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; result + &lt;span class="str"&gt;"."&lt;/span&gt; + validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This upside is that you enable you model and validations to match precisely.  The downside is that this model binder does not have a lot of re-use if you’re not using this model in multiple views.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;u&gt;Option 2 – Set your Html.ValidationMessage() differently&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this typical scenario, you’d set up your view like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Of course, this leads to the issue described above. As an alternative, you could use different name parameters like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Contact.FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The upside is that you could leverage a more re-usable binder as described in Hayden’s post.  The downside is that it seems a little counter-intuitive to be using different parameters on the TextBox() and ValiationMessage() extension methods to represent the same business object property.  Perhaps this mis-match “feels” a little better with the MvcFutures syntax:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBoxFor(m =&amp;gt; m.Contact.FirstName) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Whichever way you end up choosing, you certainly have a couple of decent options.  The fact that MVC was designed in such a flexible way to be able to give you these options in the first place speaks volumes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130144"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=130144" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/130144.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx</guid>
            <pubDate>Tue, 17 Mar 2009 03:17:22 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/130144.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/03/16/enterprise-library-validation-application-block-with-mvc-binders.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/130144.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/130144.aspx</trackback:ping>
        </item>
        <item>
            <title>Validation Application Block &amp;ndash; Unit Test Validation Logic</title>
            <link>http://geekswithblogs.net/michelotti/archive/2009/01/27/validation-application-block-ndash-unit-test-validation-logic.aspx</link>
            <description>&lt;p&gt;The Enterprise Library Validation Application Block (VAB) is a great library for putting your validation in your business layer where it belongs rather than in the UI. It allows us to apply attributes to the properties of our business objects like this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [StringLengthValidator(1, 20, MessageTemplate=&lt;span class="str"&gt;"First Name must be between 1-20 characters."&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FirstName { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    [StringLengthValidator(1, 20, MessageTemplate=&lt;span class="str"&gt;"Last Name must be between 1-20 characters."&lt;/span&gt;)]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; LastName { get; set; }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;But are you unit testing your validation code properly? Consider this test method:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[TestMethod]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Person_Validation_Test()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    var person = &lt;span class="kwrd"&gt;new&lt;/span&gt; Person();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    person.FirstName = &lt;span class="str"&gt;"Bill"&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    person.LastName = &lt;span class="str"&gt;"Gates"&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="rem"&gt;// Verify person is valid&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    var validationResults = Validation.Validate(person);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    Assert.IsTrue(validationResults.IsValid, &lt;span class="str"&gt;"Person should be valid."&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &lt;span class="rem"&gt;// Now make first name invalid&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    person.FirstName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    validationResults = Validation.Validate(person);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    Assert.IsFalse(validationResults.IsValid, &lt;span class="str"&gt;"Validation failed. FirstName should have been invalid."&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    &lt;span class="rem"&gt;// Now make last name invalid&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;    person.FirstName = &lt;span class="str"&gt;"Bill"&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    person.LastName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;    validationResults = Validation.Validate(person);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    Assert.IsFalse(validationResults.IsValid, &lt;span class="str"&gt;"Validation failed. LastName should have been invalid."&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;At first glance, this test method might look ok. It tests the person to make sure it’s valid; it then makes FirstName invalid and then tests it; it then makes LastName invalid (while setting FirstName back to normal) and then tests it, etc.  But actually, there is a long list of things that are *wrong* with that test method – do *not* unit test this way.  &lt;/p&gt;

&lt;p&gt;First off, a good unit test should only test ONE thing at a time.  In other words, you should have a test method for the FirstName property, another for the LastName property, etc.  In fact, you could have a test method for FirstName being string.Empty, another test method proving that FirstName is invalid when it is over 20 characters, etc.  Additionally, trying to “reset” the FirstName property back to normal before testing the LastName validation is just asking for trouble.  A test method constructed in this way is going to get monolithic and ultimately you’re going to forget to “reset” properly.  Additionally, you want to strive for &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself" target="_blank"&gt;DRY (Don’t Repeat Yourself)&lt;/a&gt; in your unit tests and how many times do you want to “reset” various properties back to “normal”?&lt;/p&gt;

&lt;p&gt;If that wasn’t enough, there is something even more harrowing with this test.  That is: after FirstName is set to string.Empty and validity checked for, how do we *know* that the FirstName property is the thing that is causing this object to be invalid?  Sure, it looks obvious from the method but it’s not explicit and it’s uncertain. What if setting the FirstName property actually made some composite validator invalid but the FirstName itself was perfectly valid?  What if, when we got to the LastName validation, we didn’t remember to properly “reset” the FirstName property and we’re asserting LastName is invalid where it was really the FirstName test that came before it that was making it invalid? There are just too many opportunities to make mistakes.  To simplify all of this, the unit tests can be re-written like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[TestMethod]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Person_FirstName_Is_Invalid()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    var person = CreateValidPerson();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    person.FirstName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    person.AssertWithKey(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;[TestMethod]&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Person_LastName_Is_Invalid()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    var person = CreateValidPerson();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    person.LastName = &lt;span class="kwrd"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    person.AssertWithKey(&lt;span class="str"&gt;"LastName"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;}&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Person CreateValidPerson()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    var person = &lt;span class="kwrd"&gt;new&lt;/span&gt; Person();&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;    person.FirstName = &lt;span class="str"&gt;"Bill"&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    person.LastName = &lt;span class="str"&gt;"Gates"&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    ValidationResults validationResults = Validation.Validate(person);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    Assert.IsTrue(validationResults.IsValid, &lt;span class="str"&gt;"Person should be valid."&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; person;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice that each test method is testing only one property (you can fill in additional test methods to ensure it’s invalid when over 20 characters, etc.).  Additionally, each test starts from a known, valid state by re-using the static CreateValidPerson() method (which, inside, Asserts that it is, in fact, valid).  Most importantly, for each test, it uses the AssertWithKey() method to ensure that the *reason* it is invalid is, in fact, the property we’re interested in.  This AssertWithKey() is a simple extension method:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; AssertWithKey&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; T target, &lt;span class="kwrd"&gt;string&lt;/span&gt; keyToCheck)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    ValidationResults validationResults = Validation.Validate(target);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    ValidationResult result = validationResults.FirstOrDefault(r =&amp;gt; r.Key == keyToCheck);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    Assert.IsNotNull(result, &lt;span class="str"&gt;"Validation Failed. {0} should have been invalid."&lt;/span&gt;, keyToCheck);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice the use of the FirstOrDefault() extension method.  The ValidationResults returned from the Validate() method is a collection which we can inspect to ensure that the key (the key is the property name) is tied to the validation result we are looking for and expecting – thus, ensuring that the test is in fact invalid *because* of the specific property we’re testing.&lt;/p&gt;

&lt;p&gt;The above code was written for MSTest but can be easily adapted to NUnit, xUnit, or your unit testing framework of choice.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129018"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=129018" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/129018.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2009/01/27/validation-application-block-ndash-unit-test-validation-logic.aspx</guid>
            <pubDate>Wed, 28 Jan 2009 03:27:26 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/129018.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2009/01/27/validation-application-block-ndash-unit-test-validation-logic.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/129018.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/129018.aspx</trackback:ping>
        </item>
        <item>
            <title>Enterprise Library Validation Application Block with ASP.NET MVC</title>
            <link>http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx</link>
            <description>&lt;p&gt;Several weeks ago (before the release of the CTP5 of MVC) I posted a way to &lt;a href="http://geekswithblogs.net/michelotti/archive/2008/06/17/122931.aspx" target="_blank"&gt;leverage the EntLib Validation Application Block with MVC&lt;/a&gt;. Since then CTP5 has been released and this finally includes a mechanism for reporting validations.  It is important to note that it does not include the mechanism for *how* to do validation but rather how to *report* validations.  This is actually a great thing because, first off, it allows the flexibility to utilize whatever validation framework you please rather than forcing you into a specific framework.  Additionally, it encourages validations to be handled in the business/domain layer rather than the presentation layer.  Stephen Walther shows an example here for how to &lt;a href="http://weblogs.asp.net/stephenwalther/archive/2008/09/09/asp-net-mvc-tip-42-use-the-validation-application-block.aspx" target="_blank"&gt;leverage the EntLib VAB with the latest version of MVC&lt;/a&gt;. In this post, I'm going to expand on that including discussing specific issues that need to be addressed in more real-world applications.&lt;/p&gt;  &lt;p&gt;Let's take an example:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://geekswithblogs.net/images/geekswithblogs_net/michelotti/4145/o_contactDiagram.jpg" /&gt; &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;In the simple case, let's say we pass a Contact object as the Model on to the View. To display and validation the first name we can simple do this:&lt;/p&gt; &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;  &lt;div class="csharpcode"&gt;   &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;) &lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Then in our server side C# code during postback we can do this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var validationResult &lt;span class="kwrd"&gt;in&lt;/span&gt; validationResults)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ViewData.ModelState.AddModelError(validationResult.Key, &lt;span class="kwrd"&gt;null&lt;/span&gt;, validationResult.Message);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;This is all well and good because the validationResult.Key is going to be "FirstName" (e.g., if the first name was not valid).  Basically it is just the property name.&lt;/p&gt;

&lt;p&gt;This worked fine &lt;u&gt;because&lt;/u&gt; the property name matched the string we gave the the Html.TextBox() and Html.ValidationMessage() methods. We don't have to look far to see that this will not always be this simple.  Let see what it looks like to show our Contact's Street Address:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"Address.StreetAddress"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.ValidationMessage(&lt;span class="str"&gt;"Address.StreetAddress"&lt;/span&gt;)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;Notice that now we have to specify "Address.StreetAddress" because Address is a property on the Contact object. If the street address is not valid, the C# code above will not work because the validationResult.Key is going to be "StreetAddress" but the key we need for the MVC ViewPage is "Address.StreetAddress". So basically we need is a helper method that is going to translate the Key from the ValidationResult into the key needed for the ViewPage. That is, we want to translate "StreetAddress" into "Address.StreetAddress" in this case. Even more specifically, we have to set the "prefix" correctly because we know the property names are going to match.&lt;/p&gt;

&lt;p&gt;There are several ways to solve this. One way is to use a simple property prefix map like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; propertyPrefixMap = &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;Type, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;()&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    { &lt;span class="kwrd"&gt;typeof&lt;/span&gt;(Address), &lt;span class="str"&gt;"Address"&lt;/span&gt; },&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="rem"&gt;// Add other types here&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;};&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ToMvcKey(&lt;span class="kwrd"&gt;this&lt;/span&gt; ValidationResult validationResult)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; prefix;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    propertyPrefixMap.TryGetValue(validationResult.Target.GetType(), &lt;span class="kwrd"&gt;out&lt;/span&gt; prefix);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(prefix))&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;    {&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; prefix + &lt;span class="str"&gt;"."&lt;/span&gt; + validationResult.Key;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    }&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;A couple things of note.  I'm using a C# 3.0 collection initializer on the dictionary here.  Then notice I'm using the "this" keyword to make ToMvcKey() an extension method.  Now I can change the original C# foreach loop to look like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var validationResult &lt;span class="kwrd"&gt;in&lt;/span&gt; validationResults)&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.ViewData.ModelState.AddModelError(validationResult.ToMvcKey(), &lt;span class="kwrd"&gt;null&lt;/span&gt;, validationResult.Message);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;There are many ways to make this solution more flexible. For example, we could create an overload for our extension method that allows us to pass a dictionary in since different objects might be in different places of the object hierarchy depending on the ViewPage. In any case, the flexibility that the MVC framework gives you to perform various tasks many different ways is a great thing.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=125641"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=125641" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/125641.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx</guid>
            <pubDate>Sun, 05 Oct 2008 02:15:08 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/125641.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/125641.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/125641.aspx</trackback:ping>
        </item>
        <item>
            <title>Leverage EntLib Validation Application Block in MVC</title>
            <link>http://geekswithblogs.net/michelotti/archive/2008/06/17/122931.aspx</link>
            <description>&lt;p&gt;&lt;font size="4"&gt;&lt;span style="font-weight: bold;"&gt;UPDATE: This post is now out of date as of the CTP5 release of the MVC framework. For the lastest version, &lt;/span&gt;&lt;a style="font-weight: bold;" href="http://geekswithblogs.net/michelotti/archive/2008/10/04/enterprise-library-validation-application-block-with-asp.net-mvc.aspx"&gt;see this post here&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;/p&gt;
&lt;p&gt;One of the areas of MVC that is still an open area in development is how best to handle UI validations.  There are numerous approaches currently being examined.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a target="_blank" href="http://www.codeplex.com/MVCContrib"&gt;MVCContrib&lt;/a&gt; &lt;/li&gt;
    &lt;li&gt;&lt;a target="_blank" href="http://www.codeplex.com/MvcValidatorToolkit"&gt;Validator Toolkit for MVC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Enterprise Library's VAB is great because it allows you to specify all your validation logic in your business layer where it belongs rather than in your UI.  Additionally, it comes with the PropertyProxyValidator to automatically display validation messages in the UI and avoid having to put hundreds of validators on a page.  However, the PropertyProxyValidator is a traditional ASP.NET validator control and does not work in the MVC framework.&lt;/p&gt;
&lt;p&gt;The good news here is that duplicating the functionality of the PropertyProxyValidator in the MVC framework is not difficult.  Currently, the MVC framework comes with some built-in extension methods to enable the developer to easy create UI elements hanging off the HtmlHelper property.  I've written a couple of similar extension methods following the same pattern that essentially produce the same output as the ProperyProxyValidator.  This enables us to write UI code without cluttering our mark up with a ton of validator controls:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;style type="text/css"&gt;&lt;![CDATA[
.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; }
]]&gt;&lt;/style&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.TextBox(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;, ViewData.Model.Contact.FirstName)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="asp"&gt;&amp;lt;%&lt;/span&gt;=Html.Validator(&lt;span class="str"&gt;"FirstName"&lt;/span&gt;, ViewData.Model.ValidationResults)&lt;span class="asp"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Notice that a property called "ValidationResults" is being passed in to this Validator.  When the form is submitted, it goes to a controller action (let's say "Save" for this example): &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;&lt;/p&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.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; }
]]&gt;&lt;/style&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ActionResult Save(&lt;span class="kwrd"&gt;int&lt;/span&gt; id)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    Contact contact = &lt;span class="kwrd"&gt;new&lt;/span&gt; Contact();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    contact.ContactID = id;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    BindingHelperExtensions.UpdateFrom(contact, Request.Form);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    ValidationResults validationResults = Validation.Validate(contact);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (validationResults.IsValid)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        contactManager.SaveContact(contact);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; RedirectToAction(Views.Index);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        ContactViewData contactViewData = &lt;span class="kwrd"&gt;new&lt;/span&gt; ContactViewData(contact);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        contactViewData.ValidationResults = validationResults;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        ViewData.Model = contactViewData;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; View(Views.EditContact);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;}  &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;So if the contact object in this example is valid, we save it to the database and proceed as normal to the next redirect action.  However, if the contact is not valid, we redisplay the edit contact page again and this time we pass the ValidationResults along with the existing contact object in the Model to the View.  This Validator control will grab the appropriate validation messages for the specified control/property and display any validation messages for that specific control.  The following is the complete code for the Validator extension methods:     &lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt; &lt;/p&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&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; ValidationControlExtensions&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Validator(&lt;span class="kwrd"&gt;this&lt;/span&gt; HtmlHelper html, &lt;span class="kwrd"&gt;string&lt;/span&gt; controlToValidate, ValidationResults validationResults)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; Validator(html, controlToValidate, validationResults, &lt;span class="kwrd"&gt;new&lt;/span&gt; { style=&lt;span class="str"&gt;"color:Red;"&lt;/span&gt; });&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Validator(&lt;span class="kwrd"&gt;this&lt;/span&gt; HtmlHelper html, &lt;span class="kwrd"&gt;string&lt;/span&gt; controlToValidate, ValidationResults validationResults, &lt;span class="kwrd"&gt;object&lt;/span&gt; htmlAttributes)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; Validator(html, controlToValidate, controlToValidate, validationResults, htmlAttributes);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; Validator(&lt;span class="kwrd"&gt;this&lt;/span&gt; HtmlHelper html, &lt;span class="kwrd"&gt;string&lt;/span&gt; controlToValidate, &lt;span class="kwrd"&gt;string&lt;/span&gt; propertyName, ValidationResults validationResults, &lt;span class="kwrd"&gt;object&lt;/span&gt; htmlAttributes)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (validationResults == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;        var filteredResults = validationResults.Where(r =&amp;gt; r.Key == propertyName);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (filteredResults.Count() == 0)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;        StringBuilder errorMessage = &lt;span class="kwrd"&gt;new&lt;/span&gt; StringBuilder();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ValidationResult validationResult &lt;span class="kwrd"&gt;in&lt;/span&gt; filteredResults)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt;            errorMessage.Append(validationResult.Message);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;            errorMessage.Append(&lt;span class="str"&gt;"&amp;lt;br/&amp;gt;"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        TagBuilder builder = &lt;span class="kwrd"&gt;new&lt;/span&gt; TagBuilder(&lt;span class="str"&gt;"span"&lt;/span&gt;);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;        IDictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;object&lt;/span&gt;&amp;gt; attribueDictionary = &lt;span class="kwrd"&gt;new&lt;/span&gt; RouteValueDictionary(htmlAttributes);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        builder.Attributes = ToStringDictionary(attribueDictionary);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;        builder.InnerHtml = errorMessage.ToString();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; builder.ToString();&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  39:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  40:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  41:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  42:  &lt;/span&gt;    &lt;span class="rem"&gt;/// ToStringDictionary is Internal to System.Web.Mvc.HtmlHelper&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  43:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  44:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;typeparam name="TKey"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  45:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;typeparam name="TValue"&amp;gt;&amp;lt;/typeparam&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  46:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;param name="dictionary"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  47:  &lt;/span&gt;    &lt;span class="rem"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  48:  &lt;/span&gt;    &lt;span class="kwrd"&gt;internal&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt; ToStringDictionary&amp;lt;TKey, TValue&amp;gt;(IDictionary&amp;lt;TKey, TValue&amp;gt; dictionary)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  49:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  50:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (dictionary == &lt;span class="kwrd"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  51:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  52:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Dictionary&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(StringComparer.OrdinalIgnoreCase);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  53:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  54:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; dictionary.ToDictionary&amp;lt;KeyValuePair&amp;lt;TKey, TValue&amp;gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;, &lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;(entry =&amp;gt; Convert.ToString(entry.Key, CultureInfo.InvariantCulture), entry =&amp;gt; Convert.ToString(entry.Value, CultureInfo.InvariantCulture), StringComparer.OrdinalIgnoreCase);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  55:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  56:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;One note here is that you can see I'm using a class called TagBuilder inside my method.  This is actually an internal class in the System.Web.Mvc assembly.  I just cracked open Reflector and did a complete copy/paste of that code into my own assembly so that I could leverage it.  But what would be really nice is if Microsoft would change the accessibility on that class to public to more easily enable scenarios like this when people want to build their own control extension methods.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122931"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122931" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/122931.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2008/06/17/122931.aspx</guid>
            <pubDate>Tue, 17 Jun 2008 19:47:32 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/122931.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2008/06/17/122931.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/122931.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/122931.aspx</trackback:ping>
        </item>
        <item>
            <title>EntLib Validation Application Block - Subclassing PropertyProxyValidator for ValueConvert</title>
            <link>http://geekswithblogs.net/michelotti/archive/2008/06/16/122893.aspx</link>
            <description>&lt;p&gt;The Enterprise Library VAB provides the PropertyProxyValidator for ASP.NET applications so that you can attach it to a single control and it will display any validation messages for that business object property.  This automatic UI validation is great because it avoids duplicating your business layer validation logic in your UI.  Additionally, you can just use ONE validator control whereas using traditional ASP.NET validation controls you might need to attach 3-4 validation controls to a single UI element (e.g., RequireFieldValidator, RangeValidator, RegexValidator, etc.) which can clutter your aspx pages quickly.&lt;/p&gt; &lt;p&gt;However, one of the gotchas with working with the PropertyProxyValidator control is that, while it is quite elegant for strings, you have to do a little extra work for data types such as DateTime.  Specifically, if you are working with a DateTime, you have to attach a ValueConvert method to your PropertyProxyValidator control in which you perform the data type conversion.  The following code snippet is directly out of the VAB documentation:&lt;/p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt; &lt;style type="text/css"&gt;&lt;![CDATA[
.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; }
]]&gt;&lt;/style&gt;  &lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; dateOfBirthValidator_ValueConvert(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ValueConvertEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; &lt;span class="kwrd"&gt;value&lt;/span&gt; = e.ValueToConvert &lt;span class="kwrd"&gt;as&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            e.ConvertedValue = DateTime.Parse(&lt;span class="kwrd"&gt;value&lt;/span&gt;, System.Globalization.CultureInfo.CurrentCulture);&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;        &lt;span class="kwrd"&gt;catch&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;            e.ConversionErrorMessage = &lt;span class="str"&gt;"Date Of Birth is not in the correct format."&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            e.ConvertedValue = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This extensibility is great but if I need to perform multiple DateTime validations like this throughout my application, I don't want to have to copy/paste this code everywhere.  Even if I encapsulate it in a static utility method, I still have to go through the pain of wiring up an event for any control where I need this just to make that 1-line call to the utility method.&lt;/p&gt;
&lt;p&gt;So...a better approach is to simply subclass the PropertyProxyValidator control.  In the following example, I just wire up the conversion in the contructor.  This enables me to avoid having to wire up the event in the aspx code and and also enables me to avoid having to include the event in the code behind.  I just specify the DateTimePropertyProxyValidator in my aspx code the normal way:&lt;/p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;style type="text/css"&gt;&lt;![CDATA[
.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; }
]]&gt;&lt;/style&gt;

&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="txtDateOfBirth"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;vab:DateTimePropertyProxyValidator&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="dobVal"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;span class="attr"&gt;ControlToValidate&lt;/span&gt;&lt;span class="kwrd"&gt;="txtDateOfBirth"&lt;/span&gt; &lt;span class="attr"&gt;PropertyName&lt;/span&gt;&lt;span class="kwrd"&gt;="DateOfBirth"&lt;/span&gt; &lt;span class="attr"&gt;SourceTypeName&lt;/span&gt;&lt;span class="kwrd"&gt;="Person"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The same pattern could obviously be used for other data types.  Below is the complete code for the DateTimePropertyProxyValidator:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; DateTimePropertyProxyValidator : PropertyProxyValidator&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; DateTimePropertyProxyValidator()&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.ValueConvert += OnValueConvert;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt;    &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; OnValueConvert(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, ValueConvertEventArgs e)&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;    {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;        DateTime result;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt; &lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (DateTime.TryParse((&lt;span class="kwrd"&gt;string&lt;/span&gt;)e.ValueToConvert, &lt;span class="kwrd"&gt;out&lt;/span&gt; result))&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;            e.ConvertedValue = result;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        {&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;            e.ConversionErrorMessage = &lt;span class="str"&gt;"Date is not in the correct format."&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            e.ConvertedValue = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    }&lt;/pre&gt;&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt;}&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122893"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122893" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/122893.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2008/06/16/122893.aspx</guid>
            <pubDate>Mon, 16 Jun 2008 19:19:57 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/122893.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2008/06/16/122893.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/122893.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/122893.aspx</trackback:ping>
        </item>
        <item>
            <title>EntLib Validation Application Block - Required String Validator</title>
            <link>http://geekswithblogs.net/michelotti/archive/2008/06/12/122836.aspx</link>
            <description>&lt;p&gt;In a previous &lt;a target="_blank" href="http://geekswithblogs.net/michelotti/archive/2008/06/10/122780.aspx"&gt;post&lt;/a&gt; I discussed validating strings with the VAB in the context of ASP.NET applications.  In summary, you must have a NotNullValidator and also a StringLengthValidator that prevents a string length of zero on the lower bound and prevents a string length above your upper bound (e.g., 50 characters).  That attribute might look like this:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[StringLengthValidator(1, 50, MessageTemplate=&lt;span class="str"&gt;"First Name must be 1-50 characters."&lt;/span&gt;)] &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But the problem is that the StringLengthValidator is really doing 2 jobs - one to check if the user entered a value and another to check the upper bound. Although including the NotNullValidator complete and correct, it doesn't do much in the context of asp.net applications which default to an empty string.  &lt;/p&gt;
&lt;p&gt;So from a user perspective, it would be nice to have one message if the user leaves it blank and another message if they've exceed the upper bound (or didn't follow an appropriate Regex pattern, etc., etc.).  In other words, it would be nice to have a RequiredStringValidator so we could write our business object like this (notice we no longer have to care about the lower bound on the string length validator):&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [RequiredStringValidator(MessageTemplate = &lt;span class="str"&gt;"First Name is required."&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    [StringLengthValidator(50, MessageTemplate = &lt;span class="str"&gt;"First Name must be less than 50 characters."&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FirstName { get; set; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;} &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Also, specifiying a MessageTemplate on the RequiredStringValidator is optional.&lt;/p&gt;
&lt;p&gt;So creating your own custom validator to do this is actually quite easy.  The complete implementation follows:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RequiredStringValidatorAttribute : ValueValidatorAttribute&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; Validator DoCreateValidator(Type targetType)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; RequiredStringValidator(&lt;span class="kwrd"&gt;this&lt;/span&gt;.MessageTemplate, &lt;span class="kwrd"&gt;this&lt;/span&gt;.Negated);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;}&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; RequiredStringValidator : ValueValidator&amp;lt;&lt;span class="kwrd"&gt;string&lt;/span&gt;&amp;gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; RequiredStringValidator(&lt;span class="kwrd"&gt;string&lt;/span&gt; messageTemplate, &lt;span class="kwrd"&gt;bool&lt;/span&gt; negated) : &lt;span class="kwrd"&gt;base&lt;/span&gt;(messageTemplate, &lt;span class="kwrd"&gt;null&lt;/span&gt;, negated)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  13:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  14:  &lt;/span&gt;    &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  15:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoValidate(&lt;span class="kwrd"&gt;string&lt;/span&gt; objectToValidate, &lt;span class="kwrd"&gt;object&lt;/span&gt; currentTarget, &lt;span class="kwrd"&gt;string&lt;/span&gt; key, ValidationResults validationResults)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  16:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  17:  &lt;/span&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;string&lt;/span&gt;.IsNullOrEmpty(objectToValidate) != Negated)&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  18:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  19:  &lt;/span&gt;            LogValidationResult(validationResults, GetMessage(objectToValidate, key), currentTarget, key);&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  20:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  21:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  22:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  23:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; DefaultNegatedMessageTemplate&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  24:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  25:  &lt;/span&gt;        get&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  26:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  27:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"Field cannot have a value."&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  28:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  29:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  30:  &lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  31:  &lt;/span&gt;    &lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; DefaultNonNegatedMessageTemplate&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  32:  &lt;/span&gt;    {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  33:  &lt;/span&gt;        get&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  34:  &lt;/span&gt;        {&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  35:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;"Field is required."&lt;/span&gt;;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  36:  &lt;/span&gt;        }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  37:  &lt;/span&gt;    }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;  38:  &lt;/span&gt;} &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I've supported Negations for completeness but I can't really think of a real-world example where you'd want to use it in this context.  &lt;/p&gt;
&lt;p&gt;So overall, the RequiredStringValidator check for both null and empty string.  Thus, you don't have to feel like you're kludging the StringLengthValidator into doing two different jobs.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122836"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122836" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/122836.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2008/06/12/122836.aspx</guid>
            <pubDate>Fri, 13 Jun 2008 03:23:24 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/122836.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2008/06/12/122836.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/122836.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/122836.aspx</trackback:ping>
        </item>
        <item>
            <title>EntLib Validation Application Block - Validate a string in ASP.NET</title>
            <link>http://geekswithblogs.net/michelotti/archive/2008/06/10/122780.aspx</link>
            <description>&lt;p&gt;You've created a class like this and all your unit tests pass just fine when you check for null strings or strings greater than 50 characters:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Person&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;    [NotNullValidator(MessageTemplate=&lt;span class="str"&gt;"First Name is required."&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;    [StringLengthValidator(50, MessageTemplate=&lt;span class="str"&gt;"First Name must be 1-50 characters."&lt;/span&gt;)]&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; FirstName { get; set; }&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;But then when you run it in an ASP.NET application with the PropertyProxyValidator validation control provided by VAB, your business object suddenly shows as valid even though the user left the text box blank.&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;asp:TextBox&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;="txtFirstName"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;vab:PropertyProxyValidator&lt;/span&gt; &lt;span class="attr"&gt;id&lt;/span&gt;&lt;span class="kwrd"&gt;="firstNameVal"&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;="server"&lt;/span&gt; &lt;span class="attr"&gt;ControlToValidate&lt;/span&gt;&lt;span class="kwrd"&gt;="txtFirstName"&lt;/span&gt; &lt;/pre&gt;
&lt;pre&gt;                                   &lt;span class="attr"&gt;PropertyName&lt;/span&gt;&lt;span class="kwrd"&gt;="FirstName"&lt;/span&gt; &lt;span class="attr"&gt;SourceTypeName&lt;/span&gt;&lt;span class="kwrd"&gt;="WebApplication1.Person"&lt;/span&gt;&lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Why is this happening?  The reason is because the ASP.NET infrasture will put an empty string (i.e., a zero-length string) in that property rather than a null.  In point of fact, the validator was not set up correctly to begin with.  The intent is also to prevent an empty string.  So to correct the implementation of the StringLengthValidator, you must give the lower bound of 1 as the first argument as shown here:&lt;/p&gt;
&lt;!-- code formatted by http://manoli.net/csharpformat/ --&gt;
&lt;div class="csharpcode"&gt;
&lt;pre&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;[StringLengthValidator(1, 50, MessageTemplate=&lt;span class="str"&gt;"First Name must be 1-50 characters."&lt;/span&gt;)] &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Additionally, the VAB will allow you to specify whether you want the number specified for the lower/upper bound to be considered inclusvie/exclusive for the range.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122780"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122780" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/michelotti/aggbug/122780.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Steve Michelotti</dc:creator>
            <guid>http://geekswithblogs.net/michelotti/archive/2008/06/10/122780.aspx</guid>
            <pubDate>Wed, 11 Jun 2008 01:27:42 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/michelotti/comments/122780.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/michelotti/archive/2008/06/10/122780.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/michelotti/comments/commentRss/122780.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/michelotti/services/trackbacks/122780.aspx</trackback:ping>
        </item>
    </channel>
</rss>