Can ASP.NET Routing be used to create “clean” URLs for .ashx (IHttpHander) handlers?

前端 未结 5 1888
温柔的废话
温柔的废话 2020-11-30 03:19

I have some REST services using plain old IHttpHandlers. I\'d like to generate cleaner URLs, so that I don\'t have the .ashx in the path. Is there a way to us

5条回答
  •  猫巷女王i
    2020-11-30 04:06

    EDIT: I just edited this code because I had some issues with the old one. If you're using the old version please update.

    This thread is a bit old but I just re-wrote some of the code here to do the same thing but on a more elegant way, using an extension method.

    I'm using this on ASP.net Webforms, and I like to have the ashx files on a folder and being able to call them either using routing or a normal request.

    So I pretty much grabbed shellscape's code and made an extension method that does the trick. At the end I felt that I should also support passing the IHttpHandler object instead of its Url, so I wrote and overload of the MapHttpHandlerRoute method for that.

    namespace System.Web.Routing
    {
     public class HttpHandlerRoute : IRouteHandler where T: IHttpHandler
     {
      private String _virtualPath = null;
    
      public HttpHandlerRoute(String virtualPath)
      {
       _virtualPath = virtualPath;
      }
    
      public HttpHandlerRoute() { }
    
      public IHttpHandler GetHttpHandler(RequestContext requestContext)
      {
       return Activator.CreateInstance();
      }
     }
    
     public class HttpHandlerRoute : IRouteHandler
     {
      private String _virtualPath = null;
    
      public HttpHandlerRoute(String virtualPath)
      {
       _virtualPath = virtualPath;
      }
    
      public IHttpHandler GetHttpHandler(RequestContext requestContext)
      {
       if (!string.IsNullOrEmpty(_virtualPath))
       {
        return (IHttpHandler)System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(_virtualPath, typeof(IHttpHandler));
       }
       else
       {
        throw new InvalidOperationException("HttpHandlerRoute threw an error because the virtual path to the HttpHandler is null or empty.");
       }
      }
     }
    
     public static class RoutingExtension
     {
      public static void MapHttpHandlerRoute(this RouteCollection routes, string routeName, string routeUrl, string physicalFile, RouteValueDictionary defaults = null, RouteValueDictionary constraints = null)
      {
       var route = new Route(routeUrl, defaults, constraints, new HttpHandlerRoute(physicalFile));
       routes.Add(routeName, route);
      }
    
      public static void MapHttpHandlerRoute(this RouteCollection routes, string routeName, string routeUrl, RouteValueDictionary defaults = null, RouteValueDictionary constraints = null) where T : IHttpHandler
      {
       var route = new Route(routeUrl, defaults, constraints, new HttpHandlerRoute());
       routes.Add(routeName, route);
      }
     }
    }
    

    I'm putting it inside the same namespace of all the native routing objects so it will be automatically available.

    So to use this you just have to call:

    // using the handler url
    routes.MapHttpHandlerRoute("DoSomething", "Handlers/DoSomething", "~/DoSomething.ashx");
    

    Or

    // using the type of the handler
    routes.MapHttpHandlerRoute("DoSomething", "Handlers/DoSomething");
    

    Enjoy, Alex

提交回复
热议问题