- Posted by mateid on July 16, 2010
I've broken this up into three parts:
I’ve decided to add more features to the before filter I’ve build in the previous post. I need a way to specify a few methods I’d like to execute before the controller actions. I can do that now by specifying a number of BeforeFilter attributes but that looks a little silly. What I want is the ability to do something like this:
[BeforeFilter("InitializeCategories","InitializeProvinces")]
This should be fairly easy to accomplish. We should probably start with a test. I’ve added a logaction method to the test controller so we can assert it was called. Here is the test:
[Test]
public void should_call_all_specified_controller_methods_given_they_exist()
{
controller.Setup(x => x.initialize());
controller.Setup(x => x.logaction());
var attribute = new BeforeFilterAttribute("initialize", "logaction");
attribute.OnActionExecuting(context);
controller.VerifyAll();
}
To make this pass we change our implementation slightly. The method names now become a collection we need to iterate over and invoke the method on the controller if found; if not, we throw and exception as before. I've changed the exception type to an InvalidOperationException.
public BeforeFilterAttribute(string methodName) : this(new[] { methodName })
{
}
public BeforeFilterAttribute(params string[] methods)
{
this.methods = new List<string>(methods);
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = filterContext.Controller;
foreach (var method in methods)
{
...
}
base.OnActionExecuting(filterContext);
}
This makes the test pass and now we have a BeforeFilter that’s a little more useful and friendly.
I would like to add one more feature to my BeforeFilter and that is an exception list. In other words, I would like a way to specify controller actions for which to NOT execute the methods. That way I have the ability to apply the BeforeFilter to the controller itself instead if the individual action and still retained fine grained control over the before methods that execute for a given action. I will leave that for a separate post.
- Posted by mateid on July 13, 2010
I've broken this up into three parts:
MVC2 has a nice feature called filters. They let you keep your controllers clean and factor out common code. This looks like it works particularly well for cross cutting concerns like security, logging, caching, etc. I’ve used in in one instance when I needed to populate the view bag with some common reference data used on the view to render a drop down list. With some lines omitted for brevity code for the controller looked something like this:
[HandleError]
public class ItemController : Controller
{
public ActionResult Edit()
{
ViewData["categories"] = repository.FindAll();
return View();
}
public ActionResult Create()
{
ViewData["categories"] = repository.FindAll();
return View();
}
}
We can quickly extract a method for the common code and call it InitializeCategories:
private void InitializeCategories()
{
ViewData["categories"] = repository.FindAll();
}
So you do this for a couple of controllers and you start to wonder if there is a more generic solution to this. We could try to extract a base class but that may not be suitable to all controllers or it could lead to some unpleasant inheritance hierarchy. This is when action filters come to mind. What if we could declaratively specify some method to execute before each controller action? We would like to end up with code similar to this:
[HandleError]
public class ItemController : Controller
{
[BeforeFilter("InitializeCategories")]
public ActionResult Edit()
{
return View();
}
[BeforeFilter("InitializeCategories")]
public ActionResult Create()
{
return View();
}
public void InitializeCategories()
{
ViewData["categories"] = repository.FindAll();
}
}
Writing an ActionFilter to handle this is relatively easy. There are a few types of filters available already, but for our purpose we can simply subclass ActionFilterAttribute and override the OnActionExecuting method. This method is called before out controller action executes. The method will be passed an ActionExecutingContext parameter which contains a variety of interesting information about the execution context including the controller instance. We can start by writing a test for our attribute. Lets say that we want to assert that a method on the controller is called if it exists. We make that pass and we write a second tests that asserts we throw a meaningful exception if the specified method does not exists. The tests looks like this:
[TestFixture]
public class A_BeforeFilterAttribute
{
private Mock<TestController> controller;
private ActionExecutingContext filterContext;
[SetUp]
public void Before()
{
controller = new Mock<TestController>();
filterContext = new ActionExecutingContext { Controller = controller.Object };
}
[Test]
public void should_call_the_specified_controller_method_given_it_exists()
{
controller.Setup(x => x.initialize());
var attribute = new BeforeFilterAttribute("initialize");
attribute.OnActionExecuting(filterContext);
controller.VerifyAll();
}
[Test]
public void should_throw_invalid_method_exception_given_it_doesnt_exist()
{
var attribute = new BeforeFilterAttribute("nosuchmethod");
Assert.Throws<Exception>(() => attribute.OnActionExecuting(filterContext));
controller.VerifyAll();
}
public class TestController : Controller
{
public virtual void initialize()
{
}
}
}
I created a test controller so that I can set up an expectation that its method will be called. The mocking framework I used here is Moq. The implementation that makes the tests pass is below:
public class BeforeFilterAttribute : ActionFilterAttribute
{
private readonly string methodName;
public BeforeFilterAttribute(string methodName)
{
this.methodName = methodName;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = filterContext.Controller;
var method = controller.GetType().GetMethods().Where(x => x.Name.Equals(methodName)).FirstOrDefault();
if (method == null)
{
throw new Exception(string.Format("The method {0} could not be found on {1}.", methodName, controller.GetType().FullName));
}
method.Invoke((object) controller, new object[] {});
base.OnActionExecuting(filterContext);
}
}
Kind of a lengthy posts for such short code. This can be expanded a little so that we can specify a list of methods to be called, but I haven’t needed that yet and it’s all about providing value to the customer. That could maybe look something like this:
[BeforeFilter("InitializeCategories","InitializeProvinces")]
public ActionResult Edit()
{
return View();
}
We can accomplish this by creating an overloaded constructor for the BeforeFilterAttribute:
public BeforeFilterAttribute(params string[] methodName)
{
}
That’s it for now folks, if you decide to implement the overload please share!
- Posted by mateid on July 9, 2010
A few days ago I briefly spiked mapping inheritance hierarchies with Fluent NHibernate. The result was so compelling I just have to post about it.
Based on our model we decided to go with class table inheritance. There is a brief discussion of the three well known mapping strategies in NHibernate in Action. What it boils down to is the differences in the classes. If they mostly differ by behavior class table inheritance is recommended, if the differ mostly by data than go with concrete table inheritance. Most of our differences are in behavior so we chose the former.
I used the classic sports player mode for the spike – an abstract Player class other player subclass, like a Base ballplayer for instance. I omitted model behavior from the spike since I focused on the mapping issue. The model looks like this:
public abstract class Player
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual int Age { get; set; }
}
public class BaseballPlayer : Player
{
public virtual double BattingAverage { get; set; }
}
This can be mapped manually, however is very tedious code that adds little business value to our customer. Writing this code by hand would also require a fairly significant investment in infrastructure. Instead we can map using Fluent NHibernate to it, like this:
public class PlayerClassMap : ClassMap<Player>
{
public PlayerClassMap()
{
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Age);
}
}
public class BaseballPlayerClassMap : SubclassMap<BaseballPlayer>
{
public BaseballPlayerClassMap()
{
Map(x => x.BattingAverage);
}
}
Believe it or not this all that is required to map the inheritance hierarchy above. Testing the mappings is also trivial using Fluent NHibernate’s PersitenceSpecification<T>. Here’s what the test code looks like:
[TestFixture]
public class BaseballPlayerClassMapTest : DatabaseTest
{
[Test]
public void Should_do_something()
{
new PersistenceSpecification<BaseballPlayer>(session)
.CheckProperty(x => x.Name, "Joe")
.CheckProperty(x => x.Age, 23)
.CheckProperty(x => x.BattingAverage, 0.99)
.VerifyTheMappings();
}
}
This will create a BaseballPlayer, save it to the database, load from the database and verify all the mappings. If we look at the SQL statements generated we something like this:
INSERT INTO "Player" (Name, Age) VALUES (@p0, @p1); select last_insert_rowid();@p0 = 'Joe', @p1 = 23
INSERT INTO "BaseballPlayer" (BattingAverage, Player_id) VALUES (@p0, @p1);@p0 = 0.99, @p1 = 1
SELECT baseballpl0_.Player_id as Id9_0_, baseballpl0_1_.Name as Name9_0_, baseballpl0_1_.Age as Age9_0_, baseballpl0_.BattingAverage as BattingA2_10_0_ FROM "BaseballPlayer" baseballpl0_ inner join "Player" baseballpl0_1_ on baseballpl0_.Player_id=baseballpl0_1_.Id WHERE baseballpl0_.Player_id=@p0;@p0 = 1
The table structure NHibernate will generate is below.

Our test fixtures subclass a DatabaseTest class which constructs the session and generates the database schema from our model. We use SQLite for in-memory testing which makes out integration tests pretty fast. Here’s the code for the base class.
public class DatabaseTest
{
private ISessionFactory sessionFactory;
protected ISession session;
private readonly FluentConfiguration configuration;
private readonly Configuration config;
public DatabaseTest()
{
config = new Configuration();
configuration = Fluently.Configure(config)
.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<HibernateSessionFactoryBuilder>());
}
[SetUp]
public void Setup()
{
sessionFactory = GetSessionfactory();
session = sessionFactory.OpenSession();
BuildSchema();
}
[TearDown]
public void TearDown()
{
session.Close();
session.Dispose();
}
private void BuildSchema()
{
var export = new SchemaExport(config);
export.Execute(false, true, false, session.Connection, null);
}
private ISessionFactory GetSessionfactory()
{
return configuration.BuildSessionFactory();
}
}
This one could maybe use some cleanup but that’s all we need to do to map our model to the database. We can now focus on delivering business value and not spend too much time on writing mappers and other infrastructure code.
- Posted by mateid on July 4, 2010
I am currently working on an MVC 2 project and we need basic validation for our models. An easy way to accomplish this is to use the attributes in the System.ComponetModel.DataAnnotations namespace. This works out of the box with no additional dependecies. For basic model validation you end up with something like this:
public class LoginModel
{
[Required(AllowEmptyStrings = false, ErrorMessage = "Email address is required"),
RegularExpression("@"^([a-zA-Z0-9]+[a-zA-Z0-9._%-]*@(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,4})$"", ErrorMessage = "Email address is invalid.")]
public string EmailAddress { get; set; }
public string Password { get; set; }
public bool RemeberMe { get; set; }
}
It looks a little clunky if you have a lot of attributes decorating one property, but for us it’s the simplest thing that works for now. Now we need a way to test this. My first instinct was to call Validator.TryValidate() on my model and get back the list of broken validation rules. To do this we need to first construct a validation context. The first tests looks like this:
[Test]
public void should_validate_given_a_model_with_a_missing_email_address()
{
var model = new LoginModel {EmailAddress = "", Password = "password", RemeberMe = false };
var errors = ValidateModel(model);
Assert.That(1.Equals(errors.Count()));
Assert.IsNotNull(errors.Where(x => x.ErrorMessage.Contains("Email address is required")));
}
private IEnumerable<ValidationResult> ValidateModel(LoginModel model)
{
var results = new List<ValidationResult>();
var context = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, context, results, true);
return results;
}
We needed to validate a few different models so we extracted the ValidateModel method into a base class, ValidationTestBase. The ValidateModel method is made generic so it can operate on any given model. The base class looks like this:
public class ValidationTestBase
{
protected IEnumerable<ValidationResult> ValidateModel<T>(T model)
{
var results = new List<ValidationResult>();
var context = new ValidationContext(model, null, null);
Validator.TryValidateObject(model, context, results, true);
return results;
}
}
In practice this works pretty well, and having this area well covered ensures no validation issues sneak up on us. You can easily implement a custom validator if you need something that is not provided out of the box. We had some debates around whether we should do more complex validations the same way or not. And easy example that comes to mind is check the database to determine if a user name is already taken. We decided that is better left to a service layer, and rely on the attributes only for basic data validation.
There is an equivalent open source solution to the DataAnnotations namespace – Castle.Components.Validator. The functionality provided is largely equivalent, although we didn’t explore it in detail. In a future post I will cover how to link the DataAnnotations to client side validation.
- Posted by mateid on July 4, 2010
I just spend a couple of painful hours trying to add Alex Gorbachev’s syntax highlighter to DotNetBlogEngine. I’m thinking now that if it had some useful tests this would have been a lot easier. My confidence has been shaken somewhat after looking at the source code. It’s a shame that an open source .Net project that has gained such widespread acceptance lacks a good suite of unit tests. Unfortunately attempting to retrofit the existing codebase with tests at this point could be a very painstaking exercise.
Just for the record to add the scripts and the style sheets needed you have to some hacking in BlogBasePage.cs.