Custom httphandler and routehandler with ASPNET MVC 4 and webapi

polonskyg picture polonskyg · Nov 27, 2012 · Viewed 34k times · Source

I'm working on an ASPNET MVC 4 and WebApi. The webapi methods will be consumed by mobile devices. We need to secure the services and what we are using is to encrypt the data in some particular way.

Now, I need to decrypt the call before the controller is reached. If the information decrypted is valid, it should continue to the controller as usual if not, I'll route the user to some error method.

To accomplish this I think the best bet would be custom HttpHandler and custom RouteHandler. I'm following the tutorial here

 public class MvcSecurityRouteHandler:IRouteHandler 
   { 
       public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext) 
       { 
          return new MvcSecurityHttpHandler(requestContext); 
       }
   }

public class MvcSecurityHttpHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState, IRouteHandler
    {
        public RequestContext RequestContext { get; set; }

        public MvcSecurityHttpHandler(RequestContext requestContext)
        {
            this.RequestContext = requestContext;
        }

        public bool IsReusable
        {
            get { return true; }
        }

        public void ProcessRequest(HttpContext httpContext)
        {
            var controllerId = RequestContext.RouteData.GetRequiredString("controllerId");
            IController controller = null;
            IControllerFactory factory = null;
            try
            {
                factory = ControllerBuilder.Current.GetControllerFactory();
                controller = factory.CreateController(RequestContext, controllerId);
                if (controller != null)
                {
                    controller.Execute(RequestContext);
                }
            }
            finally
            {
                factory.ReleaseController(controller);
            }

            //string originalPath = httpContext.Request.Path;
            //HttpContext.Current.RewritePath(httpContext.Request.ApplicationPath, false);
            //IHttpHandler httpHandler = new MvcHttpHandler();
            //httpHandler.ProcessRequest(HttpContext.Current);
            //HttpContext.Current.RewritePath(originalPath, false);
        }

        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        {
            throw new NotImplementedException();
        }
    }

public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            var defaults = new RouteValueDictionary
                {{"controllerId", "Home"},{"action", "Index"},{"id", string.Empty}};

            var customRoute = new Route("{controllerId}/{action}/{id}", defaults, new MvcSecurityRouteHandler());
            routes.Add(customRoute);

            routes.MapRoute(
                name: "DefaultWebApi",
                url: "{controller}/{action}/{id}",
                defaults: new
                    {
                        controller = "Home",
                        action = "Index",
                        id = UrlParameter.Optional
                    });
        }
    }

Global.asax.cs

 public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            var defaults = new RouteValueDictionary
                {{"controllerId", "Home"},{"action", "Index"},{"id", string.Empty}};

            var customRoute = new Route("{controllerId}/{action}/{id}", defaults, new MvcSecurityRouteHandler());
            routes.Add(customRoute);
        }

and in Application_Start

RegisterRoutes(RouteTable.Routes);

After the service is up, I create a breakpoint in ProcessRequest and it is not being hit. What could be missing? Is this the correct way of doing it?

Answer

trebuchet picture trebuchet · Nov 27, 2012

If you haven't yet, you need to first register the handler in global.asax or your web.config file.

http://msdn.microsoft.com/en-us/library/46c5ddfy(v=vs.100).aspx