Strongly Typed Route Data in ASP.NET MVC
Posted by: Malcolm Sheridan
in Category ASP.NET MVC
Abstract: The following article demonstrates ways to create strongly typed RouteData in ASP.NET MVC
A good practice to get into is using strongly typed objects as much as possible. This is sometimes hard to do, but try whenever you can! Recently I was working with routing data on a project, and you reference these values through RouteData, which returns a RouteValueDictionary object. To get to each route value, you need to either use an index or a string for a key. This is an area where I created a custom strongly typed object. I’m going to demonstrate two ways you can do this. Then it’s up to you to decide if this is a good model for your project.
Before moving on, you need to download ASP.NET MVC 3 RC 2. Click here to download and install them using the Microsoft Web Platform Installer.
Open studio 2010 and create a new ASP.NET MVC 3 Web Application (Razor) project. I’ve created a class called RouteValues to store the RouteData values.
Scenario 1 – Model Binding
The first option you can use is to create a custom model binder to bind the route values to a RouteValues type. Model binding is like black magic in ASP.NET MVC. Model binding is ASP.NET MVC's mechanism for mapping HTTP request data directly into action method parameters and custom .Net objects. This is good if you only need to use the route values once and not again. To create a custom model binder, all you need to do is create a class that inherits the IModelBinder interface. Here’s my custom model binder.
The custom model binder will create a new RouteValues object and fill it with the controller and action that is being requested. To use this, I need to update the global.asax file and add this custom model binder.
This basically says whenever a parameter to an action method is RouteValues, use this custom model binder. Here my action method.
If you debug the project, you’ll notice that the code jumps straight into the custom model binder, and a new RouteValues object is available in the action method with the RouteData values as strongly typed objects.
Scenario 2 – IoC with Ninject
The scenario above is good if you only need the strongly typed data once. The action only needs to accept the parameter, but what if you need this available in all your action methods? Would you make each action accept that parameter? You could, but an easier way would be to make it available to the controller through dependency injection. This basically means you inject dependencies into the controller. This scenario will use an open source Inversion of Control (IoC) container, Ninject, to pass the RouteValues type into the constructor and therefore make it available to all the action methods. I'm not going into detail about IoC or Ninject, but it is a fantastic IoC container and you can learn more about it here.
The first piece of code I want is to create a new interface called IRouteService which has one method which returns the strongly typed RouteData. Then I want a class to inherit that interface. I've put them in the same file for demonstration only.
The next thing I'm going to create is a new base class that all my controllers will derive from. The constructor will accept an IRouteService parameter. This will allow all current and future controllers access to the RouteValues class.
Next I'm going to update the controller to derive from the new base class.
Now that there always will be an RouteService object thanks to the constructor, I'll always have access to the strongly typed route data.
These were only two ways to enable strongly typed route data and you can use IoC to make your life easier when using ASP.NET MVC.
The entire source code of this article can be downloaded over here