Posts
203
Comments
1116
Trackbacks
51
October 2008 Entries
CMAP Code Camp Fall 2008 - Code Samples
The code samples from my recent presentation at the Maryland CMAP code camp can be downloaded here:

N-Tiered LINQ to SQL

MVC and Unit Testing
Posted On Monday, October 27, 2008 11:20 AM | Comments (1)
CMAP Presentation - ASP.NET MVC and Unit Testing Code Samples

The code samples from my recent presentation at the CMAP Main meeting can be downloaded here: MVC and Unit Testing. The direct download link is here.

Posted On Wednesday, October 8, 2008 7:15 PM | Comments (5)
TryParse Extension Methods

When .NET 2.0 was released, a TryParse() method was added to many value types such as Int32, DataTime, etc. This was a huge improvement because there was no longer a need to catch expensive exceptions and drag down performance. However, one drawback of the TryParse() method is that the syntax is a little clunky. The most common example looks like this:

   1:  Person person = new Person();
   2:  string value = "21";
   3:  int num;
   4:  int.TryParse(value, out num);
   5:  person.Age = num;

So it's great that we can do all this without having to catch exceptions but it definitely seems more complex than it has to be given that all we're trying to do is assign an integer to the Age property and we need this many lines of code.  We can use Extension methods to make the consuming code much more friendly - a single line of code:

   1:  person.Age = value.TryParseInt32();

To implement the static class for the extension methods, we *could* implement each TryParseXX() method like this:

   1:  public static int TryParseInt32(this string value)
   2:  {
   3:      int result;
   4:      int.TryParse(value, out result);
   5:      return result;
   6:  }

However, now we've got the ugly, repetitive code in numerous methods inside that class. On the good side, at least we've encapsulated the repetitive code inside a single class, but we can leverage a generic delegate and generic method to even avoid the repetition inside that class.

   1:  private delegate bool ParseDelegate<T>(string s, out T result);
   2:   
   3:  private static T TryParse<T>(this string value, ParseDelegate<T> parse) where T : struct
   4:  {
   5:      T result;
   6:      parse(value, out result);
   7:      return result;
   8:  }

This allows our TryParseInt32() implementation to now be a single line of code:

   1:  public static int TryParseInt32(this string value)
   2:  {
   3:      return TryParse<int>(value, int.TryParse);
   4:  }

The ParseDelegate<T> is generic that matches the signature of all the TryParse() methods. So we can imply pass in the int.TryParse delegate and it will be executed *inside* the re-useable TryParse<T> method that I have created.  This utility class can be used in all kinds of different string parsing situations.  Here is the complete code for the TryParseExtensions class:

   1:  public static class TryParseExtensions
   2:  {
   3:     
   4:      public static int TryParseInt32(this string value)
   5:      {
   6:          return TryParse<int>(value, int.TryParse);
   7:      }
   8:   
   9:      public static Int16 TryParseInt16(this string value)
  10:      {
  11:          return TryParse<Int16>(value, Int16.TryParse);
  12:      }
  13:   
  14:      public static Int64 TryParseInt64(this string value)
  15:      {
  16:          return TryParse<Int64>(value, Int64.TryParse);
  17:      }
  18:   
  19:      public static byte TryParseByte(this string value)
  20:      {
  21:          return TryParse<byte>(value, byte.TryParse);
  22:      }
  23:   
  24:      public static bool TryParseBoolean(this string value)
  25:      {
  26:          return TryParse<bool>(value, bool.TryParse);
  27:      }
  28:   
  29:      public static Single TryParseSingle(this string value)
  30:      {
  31:          return TryParse<Single>(value, Single.TryParse);
  32:      }
  33:   
  34:      public static Double TryParseDoube(this string value)
  35:      {
  36:          return TryParse<Double>(value, Double.TryParse);
  37:      }
  38:   
  39:      public static Decimal TryParseDecimal(this string value)
  40:      {
  41:          return TryParse<Decimal>(value, Decimal.TryParse);
  42:      }
  43:   
  44:      public static DateTime TryParseDateTime(this string value)
  45:      {
  46:          return TryParse<DateTime>(value, DateTime.TryParse);
  47:      }
  48:   
  49:      #region Private Members
  50:   
  51:      private delegate bool ParseDelegate<T>(string s, out T result);
  52:   
  53:      private static T TryParse<T>(this string value, ParseDelegate<T> parse) where T : struct
  54:      {
  55:          T result;
  56:          parse(value, out result);
  57:          return result;
  58:      }
  59:   
  60:      #endregion
  61:   
  62:  }
Posted On Sunday, October 5, 2008 5:30 PM | Comments (12)
Enterprise Library Validation Application Block with ASP.NET MVC

Several weeks ago (before the release of the CTP5 of MVC) I posted a way to leverage the EntLib Validation Application Block with MVC. 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 leverage the EntLib VAB with the latest version of MVC. In this post, I'm going to expand on that including discussing specific issues that need to be addressed in more real-world applications.

Let's take an example:

 

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:

   1:  <%=Html.TextBox("FirstName")%>
   2:  <%=Html.ValidationMessage("FirstName") %>

Then in our server side C# code during postback we can do this:

   1:  foreach (var validationResult in validationResults)
   2:  {
   3:      this.ViewData.ModelState.AddModelError(validationResult.Key, null, validationResult.Message);
   4:  }

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.

This worked fine because 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:

   1:  <%=Html.TextBox("Address.StreetAddress")%>
   2:  <%=Html.ValidationMessage("Address.StreetAddress")%>

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.

There are several ways to solve this. One way is to use a simple property prefix map like this:

   1:  static Dictionary<Type, string> propertyPrefixMap = new Dictionary<Type, string>()
   2:  {
   3:      { typeof(Address), "Address" },
   4:      // Add other types here
   5:  };
   6:   
   7:  public static string ToMvcKey(this ValidationResult validationResult)
   8:  {
   9:      string prefix;
  10:      propertyPrefixMap.TryGetValue(validationResult.Target.GetType(), out prefix);
  11:   
  12:      if (string.IsNullOrEmpty(prefix))
  13:      {
  14:          return validationResult.Key;
  15:      }
  16:      else
  17:      {
  18:          return prefix + "." + validationResult.Key;
  19:      }
  20:  }

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:

   1:  foreach (var validationResult in validationResults)
   2:  {
   3:      this.ViewData.ModelState.AddModelError(validationResult.ToMvcKey(), null, validationResult.Message);
   4:  }

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.

Posted On Saturday, October 4, 2008 10:15 PM | Comments (0)
CMAP Presentation - ASP.NET MVC and Unit Testing

This Tuesday I'll be giving a presentation on ASP.NET MVC and Unit Testing at the CMAP main meeting: http://www.cmap-online.org/Meetings/Details/2008-10-07.aspx .

Posted On Saturday, October 4, 2008 3:26 PM | Comments (0)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers




Google My Blog

Tag Cloud