<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>Tips</title>
        <link>http://ryanrivest.com/blog/category/2.aspx</link>
        <description>Tips</description>
        <language>en-US</language>
        <copyright>Ryan Rivest</copyright>
        <generator>Subtext Version 2.1.1.1</generator>
        <item>
            <title>Reusable Validation Error Message Resource Strings for DataAnnotations</title>
            <link>http://ryanrivest.com/blog/archive/2010/01/15/reusable-validation-error-message-resource-strings-for-dataannotations.aspx</link>
            <description>&lt;p&gt;There are quite a few examples of using the attributes from System.ComponentModel.DataAnnotations out there in your ASP.NET MVC applications.  If you haven’t been keeping up with what’s new in ASP.NET MVC 2, one of the biggest improvements is in the area of validation – which is now automatic if you decorate your models with the attributes.  I recommend you check out &lt;a href="http://weblogs.asp.net/scottgu/archive/2010/01/15/asp-net-mvc-2-model-validation.aspx" target="_blank"&gt;ScottGu’s latest epic post&lt;/a&gt; on the topic to get up to speed.&lt;/p&gt;  &lt;p&gt;Continuing with the Gu’s example, here is our Person class and the applied validation attributes:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;    public class Person {
        [Required(ErrorMessage = "First Name is required.")]
        [StringLength(50, ErrorMessage = "First Name must be under 50 characters.")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Last Name is required.")]
        [StringLength(50, ErrorMessage = "Last Name must be under 50 characters.")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "Age is required.")]
        [Range(0, 120, ErrorMessage = "Age must be between 0 and 120.")]
        public int Age { get; set; }

        [Required(ErrorMessage = "Email is required.")]
        [Email(ErrorMessage = "You did not enter a valid email.")]
        public string Email { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;This works great, but we can take it one step further and eliminate all the explicit error message strings by using a resource file.  To add one, hit &lt;strong&gt;Ctrl+Shift+A &lt;/strong&gt;to launch the &lt;strong&gt;Add New Item &lt;/strong&gt;dialog.  You can enter any name you like, I choose to keep it simple and named it Resources.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/AddResourceFile_4.gif" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="AddResourceFile" border="0" alt="AddResourceFile" src="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/AddResourceFile_thumb_1.gif" width="585" height="362" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Next, we’ll add our error message strings to the resource file.  Make note of the format items ({0}, {1}, etc.), as this is how the property names and validation attribute parameters are added to the error message.  I’ll explain how this works later in this post.  It’s also important to make sure the &lt;strong&gt;Access Modifier&lt;/strong&gt; is set to &lt;strong&gt;Public&lt;/strong&gt;.  If it’s set to Internal, ASP.NET MVC 2’s DataAnnotations Model Binder won’t validate the property at all.  This took me a few minutes to figure out what was happening, so don’t make the same mistake I did.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/ValidationErrorStrings_4.gif" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ValidationErrorStrings" border="0" alt="ValidationErrorStrings" src="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/ValidationErrorStrings_thumb_1.gif" width="541" height="208" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Now that we have our Resource file created and the validation error messages defined, we can change our Person class to make use of them.  To get this working, all you need to do is specify the &lt;strong&gt;ErrorMessageResourceName&lt;/strong&gt; and &lt;strong&gt;ErrorMessageResourceType&lt;/strong&gt; when applying a validation attribute.  Here’s our new Person class making use of the resources.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;    public class Person {
        [Required(ErrorMessageResourceName = "Required_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        [StringLength(50, ErrorMessageResourceName = "Required_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        public string FirstName { get; set; }

        [Required(ErrorMessageResourceName = "Required_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        [StringLength(50, ErrorMessageResourceName = "StringLength_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        public string LastName { get; set; }

        [Required(ErrorMessageResourceName = "Required_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        [Range(0, 120, ErrorMessageResourceName = "Range_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        public int Age { get; set; }

        [Required(ErrorMessageResourceName = "Required_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        [Email(ErrorMessageResourceName = "Email_ValidationError", ErrorMessageResourceType = typeof(Resources))]
        public string Email { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;When we test the validation, we should see that the validation still works, and it’s now using our generalized error messages, substituting the property name and, if the validation attribute has any, the attribute parameters (as in the case of StringLength or the Range attributes).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/ValidationTest_2.gif" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="ValidationTest" border="0" alt="ValidationTest" src="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/ValidationTest_thumb.gif" width="623" height="480" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It works great now, but that code still looks a little verbose to me.  I don’t want to specify the resource string name and resource type every time I use one of the attributes.  My preferred approach is to subclass the validation attributes with my own of the same name.  Let’s do that now.  The strategy here is to pass the heavy lifting off to the original attribute’s constructor (if necessary), and initialize the 2 properties that we were hard-coding before.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;    public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute {
        public RequiredAttribute() {
            ErrorMessageResourceName = "Required_ValidationError";
            ErrorMessageResourceType = typeof (Resources);
        }
    }

    public class StringLengthAttribute : System.ComponentModel.DataAnnotations.StringLengthAttribute {
        public StringLengthAttribute(int maximumLength) : base(maximumLength) {
            ErrorMessageResourceName = "StringLength_ValidationError";
            ErrorMessageResourceType = typeof (Resources);
        }
    }

    public class RangeAttribute : System.ComponentModel.DataAnnotations.RangeAttribute {
        public RangeAttribute(int minimum, int maximum) : base(minimum, maximum) {
            InitializeErrorMessageResource();
        }

        public RangeAttribute(double minimum, double maximum) : base(minimum, maximum) {
            InitializeErrorMessageResource();
        }

        public RangeAttribute(Type type, string minimum, string maximum) : base(type, minimum, maximum) {
            InitializeErrorMessageResource();
        }

        private void InitializeErrorMessageResource() {
            ErrorMessageResourceName = "Range_ValidationError";
            ErrorMessageResourceType = typeof(Resources);
        }
    }

    public class EmailAttribute : RegularExpressionAttribute {
        public EmailAttribute() : base("^[a-z0-9_\\+-]+(\\.[a-z0-9_\\+-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*\\.([a-z]{2,4})$") {
            ErrorMessageResourceName = "Email_ValidationError";
            ErrorMessageResourceType = typeof (Resources);
        }
    }&lt;/pre&gt;

&lt;p /&gt;

&lt;p /&gt;

&lt;p /&gt;

&lt;p&gt;This really cleans up our model class, which now looks like this:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;    public class Person {
        [Required]
        [StringLength(50)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(50)]
        public string LastName { get; set; }

        [Required]
        [Range(0, 120)]
        public int Age { get; set; }

        [Required]
        [Email]
        public string Email { get; set; }
    }&lt;/pre&gt;

&lt;p&gt;Much better, and our validation still works as we expected, without all the string and type duplication.  The only problem I see now is that our error messages use the exact property name, which isn’t always what we want.  For example, when the user submits the form without entering a value in the FirstName field, they receive the error message “&lt;strong&gt;&lt;span style="color: #ff0000"&gt;FirstName is required.&lt;/span&gt;&lt;/strong&gt;”  I would much rather see “First Name is required.” instead.  Good news!  They made this really easy to change for nitpickers like me.&lt;/p&gt;

&lt;p&gt;To get our property name showing up nicely, all we have to do is apply the &lt;strong&gt;DisplayName &lt;/strong&gt;attribute to the &lt;strong&gt;FirstName &lt;/strong&gt;property.&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;    [DisplayName("First Name")]
    public string FirstName { get; set; }&lt;/pre&gt;

&lt;p&gt;This also has the added benefit of updating the FirstName field’s label as well, since we’re using ASP.NET MVC 2’s strongly typed label HTML helper (which uses the property name if no display name is available).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/DisplayNameError_2.gif" rel="lightbox"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="DisplayNameError" border="0" alt="DisplayNameError" src="http://ryanrivest.com/blog/images/ryanrivest_com/blog/WindowsLiveWriter/ReusableValidationErrorMessageResourceSt_14381/DisplayNameError_thumb.gif" width="623" height="455" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;As a bonus, if we enable client side validation, everything still works!  You can see an example of this in the sample code (link below).&lt;/p&gt;

&lt;h2 /&gt;

&lt;h3&gt;How it Works:  FormatErrorMessage()&lt;/h3&gt;

&lt;p&gt;Let’s take a peek inside the FormatErrorMessage() method on the &lt;strong&gt;StringLengthAttribute&lt;/strong&gt;:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;public override string FormatErrorMessage(string name) {
    return string.Format(CultureInfo.CurrentCulture, base.ErrorMessageString, new object[] { name, this.MaximumLength });
}&lt;/pre&gt;

&lt;p&gt;Every ValidationAttribute will either inherit this method, or implement their own (if it has additional parameters, like String Length, which has a maximum length that is supplied to the attribute.  As you can see, this method is simply using string.Format, and supplying the name as {0} and the MaximumLength property as {1}.  Simple enough, right?&lt;/p&gt;

&lt;p&gt;If you want to poke around in the code, you can &lt;strong&gt;&lt;a href="http://ryanrivest.com/downloads/ReusableValidationStrings.zip" target="_blank"&gt;download the sample&lt;/a&gt;&lt;/strong&gt; here.&lt;/p&gt;&lt;img src="http://ryanrivest.com/blog/aggbug/13.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Rivest</dc:creator>
            <guid>http://ryanrivest.com/blog/archive/2010/01/15/reusable-validation-error-message-resource-strings-for-dataannotations.aspx</guid>
            <pubDate>Sat, 16 Jan 2010 07:00:21 GMT</pubDate>
            <wfw:comment>http://ryanrivest.com/blog/comments/13.aspx</wfw:comment>
            <comments>http://ryanrivest.com/blog/archive/2010/01/15/reusable-validation-error-message-resource-strings-for-dataannotations.aspx#feedback</comments>
            <wfw:commentRss>http://ryanrivest.com/blog/comments/commentRss/13.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Getting Windows Installer Projects to Upgrade Previous Versions</title>
            <link>http://ryanrivest.com/blog/archive/2009/09/12/getting-windows-installer-projects-to-upgrade-previous-versions.aspx</link>
            <description>&lt;p&gt;&lt;em&gt;This tip applies to Visual Studio 2008 and Windows Installer (Setup) Projects.  They’re used to create *.msi installers for deploying applications.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;I was having some weird issues with my setup project.  When I tested the installer against the previous version of the installer, it would run fine without reporting any errors, but when I launched my application, the changes I made weren’t showing up.  &lt;/p&gt;  &lt;p&gt;Odd, I thought.  I figured the installer wasn’t working properly.  What I was expecting was an uninstall to show up before the install ran.  This is actually the behavior in Visual Studio 2005 setup projects.  It’s different in Visual Studio 2008.&lt;/p&gt;  &lt;h3&gt;Problem&lt;/h3&gt;  &lt;p&gt;I incremented my setup project’s Version from 1.0.0 to 1.0.1, thinking this was good enough for the installer to upgrade a previous installer and grab the new application files.&lt;/p&gt;  &lt;p&gt;If you investigate further, it will become apparent that the installer did indeed run.  You’ll also discover that none of the application’s assemblies or other files have been updated after running the installer.&lt;/p&gt;  &lt;p&gt;&lt;em&gt;As I briefly alluded to above, you apparently wouldn’t have this problem in Visual Studio 2005 due to the behavior of the legacy installers.  They actually do run an uninstall on the old installer, and install the new version.  Visual Studio 2008 behaves differently.&lt;/em&gt;&lt;/p&gt;  &lt;h3&gt;Solution&lt;/h3&gt;  &lt;p&gt;There are two important steps to get the installer upgrades working properly in Visual Studio 2008.  &lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Increment the Deployment Project's Version      &lt;p&gt;For example, if your current version is 1.0.0, change it to 1.0.1 &lt;/p&gt;   &lt;/li&gt;    &lt;li&gt;Increment the file versions      &lt;p&gt;[assembly: AssemblyVersion("1.0.0.1")] [assembly: AssemblyFileVersion("1.0.0.1")] &lt;/p&gt;   &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;In Visual Studio 2008, a file version comparison occurs when the new installer runs against an older installer, replacing anything that has changed rather than running an uninstall/reinstall.  Overall it’s much nicer for upgrades, but confusing if you don’t know what’s happening and forget to change the file versions like I did.&lt;/p&gt;  &lt;h3&gt;General Rules About Installer Upgrades in Visual Studio 2008&lt;/h3&gt;  &lt;ol&gt;   &lt;li&gt;&lt;p&gt;Old and new products must have identical UpgradeCode values and different ProductCode values.&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;&lt;p&gt;Old and new products must have identical values for InstallAllUsers.&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;&lt;p&gt;New product's setup Version (the setup project, nothing to do with file versions) must be higher.&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;&lt;p&gt;All setup versions (again, not file versions) must be 1.0 or greater.&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;&lt;p&gt;Visual Studio 2008 RemovePreviousVersions is not the same as 2005 and uses file update rules. Therefore if you want to update files you must increase file versions. This is normal practice in all setups, patches, etc. that file versions are updated if they have new content.&lt;/p&gt;&lt;/li&gt;    &lt;li&gt;Visual Studio 2005 RemovePreviousVersions behaves like an uninstall of the older one, followed by an install of the new one, and rules 1-4 still need following, but you could get away with not incrementing changed file versions because of the "uninstall, then install" nature of the upgrade.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Thanks go out to Phil Wilson for the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/9ce5da29-3f37-4e7f-a548-1cbeb4a3e0a3" target="_blank"&gt;information&lt;/a&gt;!&lt;/p&gt;  &lt;p&gt;Hope this helps someone else&lt;/p&gt;&lt;img src="http://ryanrivest.com/blog/aggbug/10.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Rivest</dc:creator>
            <guid>http://ryanrivest.com/blog/archive/2009/09/12/getting-windows-installer-projects-to-upgrade-previous-versions.aspx</guid>
            <pubDate>Sat, 12 Sep 2009 08:35:11 GMT</pubDate>
            <wfw:comment>http://ryanrivest.com/blog/comments/10.aspx</wfw:comment>
            <comments>http://ryanrivest.com/blog/archive/2009/09/12/getting-windows-installer-projects-to-upgrade-previous-versions.aspx#feedback</comments>
            <wfw:commentRss>http://ryanrivest.com/blog/comments/commentRss/10.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Tip: Returning Multiple Mocks with the Same Method</title>
            <link>http://ryanrivest.com/blog/archive/2009/07/11/tip-returning-multiple-mocks-with-the-same-method.aspx</link>
            <description>&lt;p&gt;Being fairly new to unit testing, I find myself discovering all kinds of interesting challenges when trying to test my data access layer (DAL).  I had decided early on in one of my projects (with the tutelage of my supervisor and mentor) to take on the task of writing my DAL from scratch.  &lt;/p&gt;  &lt;p&gt;&lt;em&gt;Disclaimer:  I realize that data access is a problem that has already been solved (many times over), this was more of a learning exercise for me.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Part of my DAL deals with the IDbCommand.CreateParameter() method.  I ran into a problem where I wanted each subsequent call of CreateParameter() to return a different mock IDbDataParameter.  After some brief searching, I ran into a thread on &lt;a href="http://groups.google.com/group/moqdisc/browse_thread/thread/f1fb3894b9d43625/149686320e89d51b?lnk=raot"&gt;Moq Discussions&lt;/a&gt; from someone with the same problem, and a very elegant solution.&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;var parameters = new Queue&amp;lt;IDbDataParameter&amp;gt;(new[] { mockFirstParam.Object, mockSecondParam.Object }); 

mockCommand.Expect(c =&amp;gt; c.CreateParameter()).Returns(() =&amp;gt; pq.Dequeue());&lt;/pre&gt;

&lt;p&gt;First we set up a generic Queue of IDbDataParameters, initialized with an array of mock IDbDataParameter objects that have already been created. &lt;/p&gt;

&lt;p&gt;Then we set the behavior of our mock IDbCommand’s CreateParameter() method to the queue's Dequeue() method so that each subsequent call will return the next mock in the queue.&lt;/p&gt;

&lt;p&gt;We use TypeMock Isolator in our shop, so here's the same code using TypeMock Isolator's AAA syntax:&lt;/p&gt;

&lt;pre class="brush: csharp;"&gt;var parameters = new Queue&amp;lt;IDbDataParameter&amp;gt;(new[] { mockFirstParam, mockSecondParam });

Isolate.WhenCalled(() =&amp;gt; command.CreateParameter()).DoInstead(param =&amp;gt; parameters.Dequeue());&lt;/pre&gt;

&lt;p&gt;This code behaves the same as its Moq counterpart, the only difference is how we use the API.  &lt;/p&gt;

&lt;p&gt;Hope someone else finds this useful.  Thanks to the original author!&lt;/p&gt;&lt;img src="http://ryanrivest.com/blog/aggbug/7.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Ryan Rivest</dc:creator>
            <guid>http://ryanrivest.com/blog/archive/2009/07/11/tip-returning-multiple-mocks-with-the-same-method.aspx</guid>
            <pubDate>Sat, 11 Jul 2009 07:13:18 GMT</pubDate>
            <wfw:comment>http://ryanrivest.com/blog/comments/7.aspx</wfw:comment>
            <comments>http://ryanrivest.com/blog/archive/2009/07/11/tip-returning-multiple-mocks-with-the-same-method.aspx#feedback</comments>
            <wfw:commentRss>http://ryanrivest.com/blog/comments/commentRss/7.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>