Custom httphandler and routehandler with ASPNET MVC 4 and webapi

34,169

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

Share:
34,169
polonskyg
Author by

polonskyg

I'm a computer engineer who likes to work with the latest technologies not being only software but hardware as well.

Updated on August 05, 2022

Comments

  • polonskyg
    polonskyg over 1 year

    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?