Route Debugging Control for ASP.NET MVC

Phil Haack recently unveiled an improved version of his debugger a few days ago for MVC 3.  Incidentally, I had used his source code for the first version to make the same thing for ASP.NET MVC 2.  I never thought it was worth releasing because anyone could simply download the RouteDebugger source code and do it themselves.  However, since there are bound to be questions on Stack Overflow on how to do this for MVC 2, I thought I’d post the source code here.

The first thing to do is to create a Model class that will house all of the Route information:


public class RouteInformation
{
	public string Route { get; set; }
	public RouteValueDictionary RouteConstraints { get; set; }
	public RouteValueDictionary RouteDataTokens { get; set; }
	public RouteValueDictionary RouteDefaults { get; set; }
	public RouteValueDictionary RouteValues { get; set; }

	public RouteInformation()
	{
	}

	public RouteInformation(HttpContextBase httpContext)
	{
		var routeData = ((MvcHandler)httpContext.Handler).RequestContext.RouteData;
		var routeValues = routeData.Values;
		var matchedRouteBase = routeData.Route;
		var matchedRoute = matchedRouteBase as Route;
		
		if (matchedRoute != null)
		{
			Route = matchedRoute.Url ?? string.Empty;
		}

		AssignRouteValues(httpContext, routeValues);
	}

	protected virtual VirtualPathData getVirtualPathData(HttpContextBase httpContext, RouteValueDictionary routeValues)
	{
		return RouteTable.Routes.GetVirtualPath(((MvcHandler)httpContext.Handler).RequestContext, routeValues);
	}

	private void AssignRouteValues(HttpContextBase httpContext, RouteValueDictionary routeValues)
	{
		var virtualPathData = getVirtualPathData(httpContext, routeValues);

		if (virtualPathData != null)
		{
			var vpdRoute = virtualPathData.Route as Route;
			if (vpdRoute != null)
			{
				RouteDefaults = vpdRoute.Defaults;
				RouteConstraints = vpdRoute.Constraints;
				RouteDataTokens = virtualPathData.DataTokens;
				RouteValues = routeValues;
			}
		}
	}
}

If the source code for this class looks familiar, it should, it’s refactored directly from the Route Debugger Source code. The next step is to create a ViewModel class for RouteInformation, this class will include all the formatting that’s needed to make it look like this: 

Since the View shouldn’t contain logic, all of the view logic is encapsulated in this class (again, just derived from Phil Haack’s source code. Nothing special going on:


public class RouteInformationViewModel
{
	public string Route { get; private set; }
	public string RouteDefaults { get; private set; }
	public string RouteConstraints { get; private set; }

	public RouteInformation(Models.RouteInformation routeInformation)
	{
		RouteConstraints = FormatRouteValues(routeInformation.RouteConstraints);
		RouteDataTokens = FormatRouteValues(routeInformation.RouteDataTokens);
		RouteDefaults = FormatRouteValues(routeInformation.RouteDefaults);
		Route = routeInformation.Route;
	}

	public string RouteDataTokens { get; private set; }

	private static string FormatRouteValues(RouteValueDictionary values)
	{
		if (values == null || values.Count == 0)
		{
			return "(null)";
		}
		StringBuilder result = new StringBuilder();
		foreach (string key in values.Keys)
		{
			result.AppendFormat("{0} = {1}, ", key, values[key]);
		}
		result.Remove(result.Length - 2, 2);
		return result.ToString();
	}
}

The final piece two pieces are the ActionResult, and the View:

 


[ChildActionOnly]
public ActionResult RouteInformation(Member member)
{
	var context = HttpContext;
	var routeInformation = new Models.RouteInformation(context);
	var routeInformationViewModel = new RouteInformationViewModel(routeInformation);

        if (member.IsEmployee)
        {
            return PartialView(routeInformationViewModel);
        }
        return new EmptyResult();
}

 

The View (the .ascx):


<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Models.ViewModels.RouteInformation>" %>
<h5>Debug Info</h5><p>( Visible Internal Only )</p><ul>
    <li>Matched Route: <%= Model.Route %></li>
    <li>Route Defaults: <%= Model.RouteDefaults %></li>
    <li>Route Constraints : <%= Model.RouteConstraints %></li>
    <li>Route DataTokens : <%= Model.RouteDataTokens %></li>
</ul>

That’s all there is to it.

Zero Day: A Review

Geek Thrillers are hard to come by.  The last such thriller I can remember was the Cuckoo’s Egg, a novel that focuses on the nitty gritty of tracking down a hacker in the pre-WWW days.

Zero Day is a novel about a security consultant that is hired to fix the damage a virus has caused; and during this time the virus causes havoc with other computer systems as it propagates through the internet, resulting in the deaths of civilians in many walks of life: Hospital patients, nuclear power engineers, Automobile factory workers, Ships running aground, and airplanes in flight.  The virus turns out to be more sinister than first thought; and it’s a race against the clock to figure out who made it and how to stop it.

Zero Day is written as if it’s going to be turned into a movie. There isn’t a lot of backstory or internal thinking; most of the action happens ‘on the screen’, where it would be relatively simple to turn it into a movie. It’s extremely well written, and there were times that I couldn’t put it down and if I did I’d just pick it up again.  It delves into the worst-case scenario and shows just how plausible it is.  

Mark draws on his real-world experience as a Security researcher at Microsoft to bring the plausible nature of Zero Day to life.  The tools used in Zero Day mirror real-world applications; but unfortunately he doesn’t take it to the depths that followers of his blog might expect.  As a programmer I hoped for more technical information about the virus or the tools used to track it down; but the author chose to forgo that to entice a larger audience.  

If you’re expecting a thriller that goes into the depth that Cuckoo’s Egg did, you’ll be sorely disappointed. If however, you’re expecting an exciting adventure that keeps you hooked until the last page, give Zero Day a read, or five.