Ryan Rivest

  Home :: Contact :: Syndication  :: Login
  8 Posts :: 0 Stories :: 0 Comments :: 0 Trackbacks

Archives

Post Categories

Friday, January 15, 2010 #

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 ScottGu’s latest epic post on the topic to get up to speed.

Continuing with the Gu’s example, here is our Person class and the applied validation attributes:

    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; }
    }

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 Ctrl+Shift+A to launch the Add New Item dialog.  You can enter any name you like, I choose to keep it simple and named it Resources.

AddResourceFile

 

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 Access Modifier is set to Public.  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.

ValidationErrorStrings

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 ErrorMessageResourceName and ErrorMessageResourceType when applying a validation attribute.  Here’s our new Person class making use of the resources.

    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; }
    }

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).

ValidationTest

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.

    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);
        }
    }

This really cleans up our model class, which now looks like this:

    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; }
    }

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 “FirstName is required.”  I would much rather see “First Name is required.” instead.  Good news!  They made this really easy to change for nitpickers like me.

To get our property name showing up nicely, all we have to do is apply the DisplayName attribute to the FirstName property.

    [DisplayName("First Name")]
    public string FirstName { get; set; }

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).

DisplayNameError

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).

How it Works:  FormatErrorMessage()

Let’s take a peek inside the FormatErrorMessage() method on the StringLengthAttribute:

public override string FormatErrorMessage(string name) {
    return string.Format(CultureInfo.CurrentCulture, base.ErrorMessageString, new object[] { name, this.MaximumLength });
}

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?

If you want to poke around in the code, you can download the sample here.


Thursday, September 24, 2009 #

When I first discovered ASP.NET MVC, I was about to begin development on a brand new project at work.  Since I come from a more “pure” background of web development (not Web Forms), I immediately got excited when I heard about this new framework.  The pieces began to click in my mind.. *finally* an ASP.NET that doesn’t rely on the drag and drop experience and hide the true nature of the web, I thought.

Day after day I would read articles and watch conference videos about this new and exciting way to build web apps with ASP.NET.  Around the same time, I started learning about unit testing and Test Driven Development (TDD).  It just so happens that the authors of ASP.NET MVC designed their framework with testability as a first-class citizen, so TDD is a natural fit.  So natural, in fact, that you were sometimes hard-pressed to find an introduction to ASP.NET MVC without a cameo by TDD.  Often people wondered whether you were required to use TDD to build apps with ASP.NET MVC.

Everyone mentions how well the framework lends itself to TDD, but few actually explain how you would go about building an application with TDD straightaway.  Steven Anderson’s book Pro ASP.NET MVC has a great introductory tutorial for building a working application with a test-first approach, but his book is so in depth (a good thing!), that sometimes the process gets a little lost in the background.

Recently I picked up a copy of ASP.NET MVC 1.0 Test Driven Development: Problem - Design - Solution by Emad Ibrahim

This is the book that I have been waiting for since ASP.NET MVC came out.  I’ve already read books explaining the details of ASP.NET MVC, so I wasn’t looking for another book to explain every aspect of the framework.  This isn’t an in-depth book on TDD or ASP.NET MVC, so if you’re looking for reference material on ASP.NET MVC, I recommend you look elsewhere, as there are several excellent books that have been out for a while.  I’ve had the pleasure of reading all three of the books I linked, and they’re all very good, in-depth technical resources if you’re looking for a book to explain every aspect of the framework.

ASP.NET MVC 1.0 Test Driven Development is essentially a ~260 page tutorial for building an application with ASP.NET MVC using the TDD process.  Some familiarity with both of them is necessary to get the most of this book.  If you’re not at least mildly comfortable with unit testing, you will have a problem reading this book.  The same goes for ASP.NET MVC.

The theme is centered around a bulk email/newsletter distribution web application called EvenContact and the author takes us through the entire development process, starting with the high-level requirements for what the application needs to do. 

This was the first Problem – Design – Solution title I’ve read from Wrox, and I really appreciated the structure of each chapter.  It highlighted the goals for each chapter by defining what the requirements were for a certain feature, the high-level design, and the author’s implementation.  It made things really clear.

Even though it was surface level, I enjoyed the overview of methodologies and design patterns in chapter 1.  It was a good introduction to the tools and practices that he would be using throughout the book, and I appreciated the introduction, which would be perfect if I had not seen the patterns before.

There were some artifacts left behind from pre-release versions of ASP.NET MVC 1.0 that I would have liked to see accurately reflected in the text.  Luckily for me, it was a non-issue because I followed most of the development changes from the CTP’s, but I can see this being confusing to newcomers.

One other important point to note – if you’re the type of person who gets lost easily when details are left out, this may not be the book for you.  The author leaves out a lot of fluff when he’s explaining new concepts and features.  Personally, I appreciated not having to go through the same steps for every single new feature in the application, but it may be something to consider for you.  I should also note that because of this fact, there are a lot of features that appear out of thin air in the text.

Even with the author’s intent to keep the book interesting by not repeating the same steps, the book does feel a bit repetitive.  We end up seeing the same tests repeated often for each new feature, and I found myself skim-reading through a lot of the second half, because it was things I had seen in the book already.

There were quite a few other typos and errors here and there in the text as well, which was surprising for a published book, but I guess it’s acceptable for a first edition.  Nonetheless, looking past the nitpicking, I still feel that it was a pretty good book, and may be a good reference for the combination of TDD and ASP.NET MVC.  There were definitely some takeaways that I got from the book and will be putting into use immediately.


Saturday, September 12, 2009 #

This tip applies to Visual Studio 2008 and Windows Installer (Setup) Projects.  They’re used to create *.msi installers for deploying applications.

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. 

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.

Problem

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.

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.

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.

Solution

There are two important steps to get the installer upgrades working properly in Visual Studio 2008. 

  1. Increment the Deployment Project's Version

    For example, if your current version is 1.0.0, change it to 1.0.1

  2. Increment the file versions

    [assembly: AssemblyVersion("1.0.0.1")] [assembly: AssemblyFileVersion("1.0.0.1")]

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.

General Rules About Installer Upgrades in Visual Studio 2008

  1. Old and new products must have identical UpgradeCode values and different ProductCode values.

  2. Old and new products must have identical values for InstallAllUsers.

  3. New product's setup Version (the setup project, nothing to do with file versions) must be higher.

  4. All setup versions (again, not file versions) must be 1.0 or greater.

  5. 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.

  6. 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.

Thanks go out to Phil Wilson for the information!

Hope this helps someone else


I’m sure many of you have seen this arcade game in a local mall or arcade..

This is the face of pure evil.

stacker

It’s called Stacker.  The object of the game is to stack blocks on top of each other.. it’s simple.. but deceptively so.  You start with 3-block lines, and as you go up it’s sliced down to 2-block lines, and finally down to 1-block lines..

It’s so addictive, and here’s why.. these Stacker machines are prize vending games.  Usually they’ll have some great prizes like an Xbox 360, Wii, or other high ticket items.  Who wouldn’t want a $300 piece of hardware for $1?  Sweet deal right?

And that’s where they suck you in.

You see.. the game is so easy.  You think you’re going to win.. no, you KNOW you’re going to win.  Just one more dollar.. and on and on.  I spent about $10 on this game and noticed something:  Stacker is rigged.

Yep, you heard me.  The last 4 lines in this game are rigged.  After you pass up the “minor prize” to continue playing for a “major prize,” the lines will randomly skip a block.  It’s very discreet, but you can catch it if you watch closely.  This YouTube video illustrates this behavior clearly, and you will also see it happen if you play a few times past the minor prize.  It’s so addictive though.  The game makes you think that you’re going to win because it’s so simple, but the fact of the matter is that it’s based more on luck than skill.

The game is set up so that the owners can set the win ratio.  What this means is that you’ll never win unless you win by chance.

They can even set the speed at which the block lines move.  Some Stacker games are MUCH faster than others.  And it’s all regulated by the owners.

Want to learn more about these games?  They’re made by LAI Games International.  A “standard” Stacker (pictured above) sells for about $5,500.  Estimating the amount of dollars that go into these things before they spit out a prize, I’m guessing they earn much more than the initial cost and prize payouts.

If you want to win on these machines, I recommend not spending more than a few bucks, because you might get lucky and hit when it’s spitting out prizes.  Otherwise, you’ll just be wasting $$ on a game that is impossible to win.

If you’re still curious, check out this video on How to Win at Stacker.

Also, if you’re a fan of the gameplay (or want to practice), there’s a flash game called Bildy Blocks that is exactly the same.


Friday, September 11, 2009 #

Did you know that you can upgrade from Windows Vista to Windows 7 for almost nothing?  You only have to pay the cost of shipping ($9.99).

There is a catch though..

You must have purchased your copy of Vista between June 26, 2009 and January 31, 2010 to be eligible, and you also need to send a copy of your receipt to Microsoft.

In addition, you must have a version of Vista that corresponds to the version of Windows 7 that you want.  More details below..

Equivalent Windows Vista products for Windows 7

Windows Vista Home Premium -> Windows 7 Home Premium
Windows Vista Business -> Windows 7 Professional
Windows Vista Ultimate -> Windows 7 Ultimate

Here’s the address if your copy of Vista is eligible.

I had some issues opening the link before, so if the link above doesn’t work, go to this one and click the text that says “from Microsoft” at the bottom (in the disclaimer).

Screenshot of the link to search for, if the first one isn’t working..

Windows7 upgrade Link

Saturday, July 11, 2009 #

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. 

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.

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 Moq Discussions from someone with the same problem, and a very elegant solution.

var parameters = new Queue<IDbDataParameter>(new[] { mockFirstParam.Object, mockSecondParam.Object }); 

mockCommand.Expect(c => c.CreateParameter()).Returns(() => pq.Dequeue());

First we set up a generic Queue of IDbDataParameters, initialized with an array of mock IDbDataParameter objects that have already been created.

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.

We use TypeMock Isolator in our shop, so here's the same code using TypeMock Isolator's AAA syntax:

var parameters = new Queue<IDbDataParameter>(new[] { mockFirstParam, mockSecondParam });

Isolate.WhenCalled(() => command.CreateParameter()).DoInstead(param => parameters.Dequeue());

This code behaves the same as its Moq counterpart, the only difference is how we use the API. 

Hope someone else finds this useful.  Thanks to the original author!


Friday, July 03, 2009 #

I recently finished reading The Art of Unit Testing by Roy Osherove (published by Manning).

As the title implies, this book covers the topic of unit testing, which is still a mystery for a lot of developers. Unfortunately, I think that many believe unit testing to be a shadowy art that seems hard to grok, and even harder to practice.  The truth is, it’s not as hard as you might think, and once you understand what unit testing truly is, you may find yourself enjoying writing your unit tests as much as your production code.

The examples in the book are in .NET, so having an understanding of C# (or a similar language) will be helpful.  An understanding of .NET unit testing frameworks might be helpful as well, but it's definitely not necessary.  The book is ripe with great examples, and the author starts at the basics, so any developer should be able to understand unit testing with or without any sort of unit testing experience.

The book is organized into four parts, which I have outlined below:

1. Getting Started

Roy sets the foundation with a great introduction to the basics of unit testing. He defines what makes a good unit test, and what the differences are between unit and integration tests.

A brief introduction to Test Driven Development is also provided at the end of the first chapter. This is one area that I wish the book would have had more of an emphasis on, but I understand that the author didn't want to fray from the overall direction of the book.

The second half of part one walks you through setting up your first unit testing framework – NUnit.  Then the author tells you how to write your first unit tests and run them with the NUnit GUI test runner.

2. Core Techniques

Obviously we're not always working with a perfectly decoupled system that was built with unit testing in mind, and we don't always have the luxury to work on Greenfield projects. As developers, we spend a lot of time in the maintenance phase, making improvements to existing legacy code.

This is testing in the real world, and where fake objects come into play.

Roy introduces both kinds of fake objects - mocks and stubs. Prior to reading this part of the book, I didn't really know (or care) the difference between a mock and a stub. But we are introduced to both sides of the spectrum, including handwritten mocks and stubs.

There is also a great deal of time spent showing us how to refactor our designs to be more testable by including seams that allow us to easily swap dependencies with fakes.

We can finally understand how to use Isolation (mock object) Frameworks by the end of chapter 5 - which is dedicated entirely to them. There's an abundance of examples showing us how to utilize Rhino Mocks to create our fakes, and some time is spent with TypeMock Isolator as well.

3. The Test Code

Personally, this was my favorite part of the book. I really enjoyed these chapters because it's not an area that I've heard a lot about.  What are the pillars of good unit tests? In the author's words, it means writing tests that are:

  • Trustworthy
  • Maintainable
  • Readable

I haven’t seen a lot of writing on the topic of unit test maintainability, and sometimes I wonder if it’s a second-class citizen. Fortunately, there's a whole part of the book dedicated to what good unit tests are, and how you should organizing your tests.

4. Design and Process

The conclusion of the book comes with an interesting twist that is a little less technical, and more political. The chapter is called: Integrating unit testing into the organization, and the author speaks from a number of experiences with unit testing and some tips for how you might successfully introduce it into your organization.

If you've ever been in an organization that was starting to practice unit testing, you've probably seen how people initially react. It's one of those areas that is scary for a lot of people because they don't fully understand it. It's also hard to learn if you have no guidance, and it can significantly increase the development time for a project when you're starting.

Fortunately, the author arms us with guidelines for successfully introducing unit testing into our organizations. There's also an entire section called "Tough questions and answers," that is devoted entirely to helping to predict the hard questions that you will undoubtedly face when starting to discuss unit testing at work.

Finally, the last chapter is dedicated to writing tests for legacy code. Roy outlines a strategy for developing tests for existing systems that don't have any unit tests. He shows you how to prioritize the components based on different characteristics, so that you can figure out what to tackle first. Large legacy codebases can be overwhelming, and having a plan of attack will be greatly beneficial!

Overall, I thought the book was excellent. It's a great front to back overview of unit testing, ranging from the absolute basics, to more advanced topics like test hierarchies, writing maintainable tests, and more.  I wish this book was around when I was just starting to unit test.  I’m recommending it to all of my friends – beginners and veterans!

Learn more at Roy Osherove's blog, and the book website at The Art of Unit Testing


Wednesday, May 20, 2009 #

Background

Well the site is finally live.  It’s been in the back of my mind for quite a while now to get a blog started, so I’m glad to finally have it up and running.

I’m running on Subtext.  ASP.NET hosting is a change for me as most of my sites in the past have been LAMP-based, but having been working with .NET for about a year now professionally, I’m more comfortable running a site with it.  My only complaint thus far is how expensive hosting is compared to a typical PHP/MySQL setup.  SQL Server hosting in particular is quite pricey!  But I digress.. back to the the main point - the blog :)

I’ve wanted to do this for a while but I hadn’t convinced myself to get this thing going until a few weeks ago when I saw a great post from Scott Hanselman pop up in my feeds.  In his Devscovery NYC keynote, Social Networking for Developers, Scott talks a bit about how having a blog can make you a better developer.  I won’t go into depth here, but if you haven’t seen the talk I recommend watching it.  It’s an interesting discussion and he gives a lot of great tips for running a successful blog.

Fast forward to now.  I installed Subtext and my site is up and running.  I know it’s a little rough around the edges.  I plan on updating the site in the future with a flashier design and other good bits, but for now this will work.

 

Who am I?

My name is Ryan.  I’m a professional software developer currently working as a systems analyst.  I graduated with my bachelor’s degree in May 2008 and started my professional career in July 2008.  I’ve learned a lot over the last year in the industry, and I hope to share that knowledge with you.

 

What is this blog going to be about?

I’ll be focusing on software development topics in my future blog posts.  I’m currently working with the .NET Framework, so my blog will be heavily influenced with all types of things in the .NET world.  I have a passion for all things web development, so there will be a lot in that area specifically.

I don’t plan on sticking to any area exclusively as of right now.  I may also post things like book reviews and other technology-related topics, with sprinkles of random other things here and there.  I hope that you interact with me via comments – I would love to hear from you!