Saturday, November 29, 2008

JQuery Form Validation Plugin

This weekend I sat down intent on finishing a portion of my media management application and testing different strategies regarding client side validation of data using the JQuery Validation Plugin (link).

My initial impressions of this plugin were, at first, not very positive, though a lot of this was the learning curve associated with grasping the rather fragmented documentation in certain areas.  Basically what I was looking for from a plugin was to easily be able to define standard validation requirements (required, minlength, equality, range) easily, as well as the flexibility to define my own( Asynchronous uniqueness check against a database ).

Below is some code from my application demonstrating the definitions of required and minlength rules:

$("form").validate({
     rules: {
          seriesName: {
               required: true,
               minlength: 2
          }
     },
     messages: {
          seriesName: {
               required: "Field is required",
               minlength: "Name must be at least 2 characters"
          }
     },
     errorElement: "div"
});

The idea here is that the parent key names (seriesName in this case) relate to the form elements themselves.  The documentation on what can be done is very skimpy, and takes a fair amount of deduction to figure out. If you look here you can get an idea of the types of validation rules that exist.  But, if your like me, you want to see this in code to see how its used, and for that there is a good example provided here, just do a view source to see the code.

Most of this will be focused with what rules you can define for various elements, the next step would be how do you communicate to the user what is wrong and what is the flexibility of what you can do.  Based on the provided examples, and my own experience, I was able to mutate the type of container the error messages were being displayed with, and the class, thus I could properly style and display them in any manner I desired.  There are a whole host of options for controlling this behavior, listed here.

In the example I provided above, I took most of the default and simply changed the element type to a <div> instead of label, which is the default element.

So at this point, we have a relatively simple call to a JavaScript method that allows us to use rule based validation setup without coding a lot of redundant JavaScript to perform the validation.  Validate will also internally check if the selected form is valid and suppress the submit if it is not valid.

The final component I was looking for was a way to implement custom validation and I was very impressed with how the Validation plugin handles this.  First some code:

$.validator.addMethod("IsUniqueName", function(value, element) {
     var id = Number($("#seriesId").val());
     var result = $.ajax({
          async: false,
          type: "GET",
          url: GetApplicationPath("#hidAppPath")
                    + "/Series/AjaxCheckSeriesName",
          data: { seriesName: value, seriesId: id },
          cache: false,
          dataType: "json"
     });
 
     if (result.responseText == "false")
          return false;
     else
          return true;
            
}, "Series name must be unique");

I found this to be very ingenious and admitting confusing the first time I read the documentation (though it was 4am and I had just finished Wave 50 Hardcore on Security in GoW2), but its actually rather simple.  If you notice above we have the key's required and minlength, these are simply built in definitions, but using the addMethod we can add our own internal rules.

In the case above, I am creating a new rule called IsUniqueName and defining as its function check a routine to make a call to a routine to verify the provided name is unique.  The final parameter is the message to be displayed in the event the two values (expected and actual) do not match up.  To specify the expected, we modify our existing call to validate as such:

rules: {
     seriesName: {
          required: true,
          minlength: 2,
          IsUniqueName: true
     }
},

Notice the new addition here, we are saying that for the rule IsUniqueName we are expecting a value of true from the callback.  Notice that I am using a block Ajax call to determine this, mainly because a callback would not be able to directly return the handler.  This is a weakness of doing this kind of check inline, instead of having the user request it.

Overall, I found that working with this plugin to be a little bit confusing at first and the documentation seemed scattered.  However, the more I stayed with it the easier it became.  This plugin adequately offers the ability to easily do standard validation as well as custom validation with a minimal amount of custom code needed.  This is important as validation tends to have a lot of redundancy involved in performing it, so a tool such as this makes that process much less error prone.  I should point out that the total LOC was 39 lines for everything that I am doing.  The amount of time this will save in future projects is well worth learning this tool and finding out all it has to offer, and that is actually quite a bit.

Below are the links I referenced in this article:

Tuesday, November 25, 2008

Programming Decorator + Notification Pattern

Recently, I was asked to rework the code which handled our companies internal expense tracking for projects.  Before I get into the solution let me first describe the workflow and some details a long with it:

  1. Expense entry is submitted for a valid project so long as it falls within the budgetary guidelines for the project
  2. The entry is then saved as an Unapproved expense to such a table within the database. If this save is occurring on a such a date as to make the expense late an email is sent out as well
  3. The expense is then reviewed by the project manager and approved or rejected.  When approved it is moved from the Unapproved table to the Approved table

Pretty simple for the most part.  The one thing that irked me was because it used two tables it used two different entities.  This would mean that I would have to know which entity I wanted to work with, that is where I started to consider the Decorator pattern.  The reason for this is, I don't feel that I should care about which entity I am updating, that code already exists, I just need to determine if I can call it.  For the most part the two entities share many common property, just with different names, so they can easily be united using an interface. In addition, the union of properties between the two, I also made visible Save and Delete routines.  This way I could create my decorator containing my single reference to the underlying entity via a abstract type:

public class ExpenseEntry : IExpenseEntity, INotifyPropertyChanged
{
     private IExpenseEntity _entity;
}

This is the definition for the Decorator class which I chose to call ExpenseEntry.  Notice how it implements our IExpenseEntity interface, which guarantees that interacting with the parent is the same as interacting with the underlying entities. Remember the decorator contains properties that are designed to talk to underlying object.

One of the requirements is that we want to know when certain properties change as it may or may not throw the underlying object into a invalid state depending on context.  Basically, business rules state that only administrators can modify the entry once it has been approved.  This class contains a simple boolean flag to specify whether the class is being used in such a context. However, the case exists that within a given week an approved and unapproved expense can exist, so we need to make sure we are leaving approved expenses alone and not notifying the user of failure unless they try to modify it.  This is where the Notification pattern comes in, in that we want to make sure that we have an easy and clean way to notify the parent that something changed and respond appropriately.  Here is the code in the Decorator for handling the event:

public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged<T>(T oldValue, T newValue)
{
  PropertyChangedEventHandler handler = PropertyChanged;
  if (handler != null && !oldValue.Equals(newValue))
  {
    handler(null, new PropertyChangedEventArgs(string.Empty));
  }
}

The important thing to see here is that if the two entries match we do NOT fire the event as there would be no need to do so.  Notice we are using generics so that we can use this handler with a variety of data types, this is because the properties we will be monitoring also vary in type and our goal is to have a single point of monitoring.

If the event is triggered the handler simply flips a boolean member variable (_dirty) to true.  This variable comes into play when the context is examined as Save is called, an exception is raised if the state is not valid for saving.

This is nothing new to may developers in the world, nor is it necessarily anything spectacular.  But I am slowly beginning to see the fruits of my interaction with the other intelligent manifest themselves, through more pattern thinking to the questions I ask and when I ask them. Initially this solution used a generic event handler which some more complex logic. I have since simplified it, but I recall commenting to a co-worker that before I came here I would never have dreamed writing code like this, but now it feels so natural. Evolution of the mind truly is a wonderful thing to behold.

Sunday, November 16, 2008

ASP .NET MVC Authentication Strategies

During the weekend I decided to try out a few strategies for protecting content against anonymous users.  During this I got the chance to explore creating custom attributes as well as gaining a better understanding of how routing really works. Ultimately I came up with a very decent solution but not the most desirable in my mind.

First Attempt: Custom Attribute
For the first attempt I took the standard ActionFilterAttribute and derived from it to create the following attribute class:

public class IsAuthenticatedAttribute : ActionFilterAttribute
{
     public override void OnActionExecuting(ActionExecutingContext filterContext)
     {
          if (!HttpContext.Current.User.Identity.IsAuthenticated)
          {
               string redirectPath = FormsAuthentication.LoginUrl;
               HttpContext.Current.Response.Redirect(redirectPath, true);
          }
     }
}

This is a very rudimentary example of deriving from the ActionFilter attribute, I have seen examples where a custom attribute is used for logging and other reporting features. What happens in this example is we are override the OnActionExecuting method from the base class, so before the method this is decorating is executed this code will execute.  As you can see, if the user is not authenticated we redirect to the login url specified in the web.config.

This is not a bad strategy, and is the strategy I am using at present within my application. However, it was not the approach I was looking for, mainly because I still have to remember to put the attribute on the methods.  What I really would like is a single place that enforces the requirement that a user must be logged in for certain action to take place.  Furthermore, I would like to be able to split up a controller's functionality for its admin and non admin actions.

Second Attempt: Routing
Based on my requirements, I naturally decided to look at routing as a means to prevent access to a particular path (aka namespace).  To begin, I created a directory under controllers (an Area as the term is known in the MVC world) called Admin and a controller called Series here to compliment the Series controller in the parent directory.

My first attempt was to institute a specific route for the admin actions and apply a constraint to the route that requires the user to be logged in, if they wish to access it, below is the following code I created:

routes.MapRoute(
     "Admin",
     "Admin/{controller}/{action}/{id}",
     new { controller = "Series", action = "Index", id = 0 },
     new {
          isLoggedIn = new AuthenticatedPathConstraint()
     },
     new string[] { 
          "AnimeManager.Controllers.Admin"
     }
);

The fourth parameter to MapRoute is a listing of the constraints to apply to this route.  Constraints are classes that implement IRouteConstraint and are passed in via an arbitrary property name in an anonymous class:

public class AuthenticatedPathConstraint : IRouteConstraint
{
     #region IRouteConstraint Members
     public bool Match(HttpContextBase httpContext, Route route,
          string parameterName, RouteValueDictionary values,
          RouteDirection routeDirection)
     {
          if (routeDirection != RouteDirection.UrlGeneration)
          {
               if (!httpContext.User.Identity.IsAuthenticated)
               {
                    httpContext.Response.Redirect(
                         FormsAuthentication.LoginUrl);
                    return false;
                }
                return true;
          }
           return true;
     }
     #endregion
}

The next parameter is a set of strings representing namespaces to search. When the MVC framework looks for controllers it, by default, re-curses through the Controllers directory and makes a string list of all controller names. Thus if you have controllers with the same name, even in a different space, you will get a server error with respect to the inherent ambiguity created.  The strings provided to the fifth parameter of MapRoute serves to restrict the namespaces where MVC will look for potential controllers.

Now, I want to return to the constraint to explain a small, but critical, piece to this.  The comparison against the RouteDirection enum is very important.  Using ActionLink from the Html helper will invoke the routing mechanism as well as accessing a particular Url.  Because of the way we are doing the redirection we want to allow UrlGeneration to occur regardless of state.  To clarify, if we dont have this logic, when generating the link the page will never load and redirect endlessly.

To actually properly use this feature we need to use the GenerateLink Html Helper extension method as such:

<%= Html.GenerateLink(
     "test", "Admin", "Index", "Series",
     new RouteValueDictionary(new { id = 12 }), null)
%>

Using GenerateLink we can actually describe which route we want to use to generate the final link.  Remember anytime we call ActionLink we invoke the underlying routing system to generate the final URL, the same is true for GenerateLink, except it allows to tell what path we wish to use in the routing table.  Because of this, I decided to keep a Default route map and place all subsequent routes following and refer to them by name as needed.

Conclusion
Both strategies do a good job in minimizing the amount of code needed to protect functionality and consolidating the logic to determine authentication status to a single place.  I personally prefer the level of control I can get using Attributes over routing, granted the routing system still need a bit more work and research, I think it could be a very acceptable method in the future.