ASP.Net MVC Framework - Creating a IRouteHandler which will support Interceptors

I really love how extensible the ASP.Net MVC Framework is, for example the normal pipeline looks like this:

Request -> Route (IRouteHandler) –> ControlFactory (IControllerFactory) -> Controller (IController) -> ViewFactory (IViewFactory) -> View (IView) -> Response

By implementing my own IrouteHandler I changed the pipeline to support Interceptors before and after an action is invoked:

Request -> Route (IRouteHandler) –> ControlFactory (IControllerFactory) -> (Pre) Interceptors (IInterceptor) -> Controller (IController) -> ViewFactory (IViewFactory) -> View (IView) -> (Post)Interceptors (Iinterceptor) -> Response

On the Controller base class we have two methods, OnPreAction and OnPostAction, those methods will be executed before and after an Action method. But I wanted to be able to specify Interceptors for a Route which should be executed before a controller is instantiated and after a Controller’s action method is executed.

The Interceptors has two methods, PreHandle and PostHandle. The PreHandle returns a value if the process of a request should be stopped or if it should go on with the process of an execution.  It’s possible to create a chain of Interceptors. If more than one Interceptor is specified and one of them tells to stop the process, the rest in the chain will not be executed. To specify an Interceptor or a chain of Interceptors I have override the Route class and created my own which has a List of IInterceptors. So when a Route is setup, Interceptors could be added to that route:

RouteTable.Routes.Add(new Nsquared2.MVC.Extenstion.Route
{
   Url = "[controller]/[action]/[id]",
   Defaults = new { action = "Index", id = (string)null },
   RouteHandler = typeof(N2MVCRouteHandler),
   Interceptors = new List<IInterceptors>()
   {
       new MyInterceptor(),
       new AnotherInterceptor()
   }
});

Here is an example of an Interceptor which will redirect the user to a “Not available at this time” page if the current time of the Request is not within a specified interval.

public bool PreHandle(RequestContext context)
{
   if (DateTime.Now.Hour > START_HOUR && DateTime.Now.Hour < END_HOUR)
           return true;
   else
       context.HttpContext.Repsonse.Redirect(“NotAvailableAtThisTime.html”);

   return false;
}

The following is my implementation of the MvcHandler’s ProcessRequest to add the Interceptors to the pipeline; the code is also part of my own MvcHandler written in my previous post.

protected override void ProcessRequest(IHttpContext httpContext)
{
   if (this.RequestContext == null)
      throw new InvalidOperationException("No RequestContext");

   if (base.RequestContext.RouteData.Route.GetType().IsAssignableFrom(typeof(Nsquared2.MVC.Exstension.Route)))
   {
       if (InterceptorHandler.ExecutePreHandler(this.RequestContext))
       {
          ControllerContext controllerContext = this.ExecuteAction();

          InterceptorHandler.ExecutePostHandler(controllerContext);
       }
   }
   else
   {
       this.ExecuteAction();
   }
}

Here is the ExecutePreHandler method of my InterceptorHandler:

public static bool ExecutePreHandler(RequestContext request)
{
   Nsquared2.MVC.Extension .Route route = request.RouteData.Route as Nsquared2.MVC.Extension.Route;

   if (route.Interceptors != null)
   {
      foreach (IInterceptors interceptor in route.Interceptors)
         if (!interceptor.PreHandle(request))
           return false;
   }

   return true;
 }

Note: This code is only used for a Interceptor prototype.

Published Monday, November 19, 2007 12:42 AM by Fredrik N
Filed under: ,

Comments

# re: ASP.Net MVC Framework - Creating a IRouteHandler which will support Interceptors

Sunday, July 6, 2008 4:20 AM by Mohamed Meligy

Do you have any idea why did the ASP.NET MVC guys re-invent the UriTemplate features (already existing in .NET 3.5) and created this whole routing stuff instead ?

Leave a Comment

(required) 
(required) 
(optional)
(required)