HttpHandler not working - General Discussions - General Discussions - Progress Community
 General Discussions

HttpHandler not working

  • HttpHandler not working
  • I have a custom HttpHandler for a specific URL (e.g. my.page), but SF keeps processing the request and giving a 404.

    Any suggestions?
  • Hello Eric,

    Could you provide some more description about the custom handler you have and what is its purpose? Generally you can create a new class that inheirits from PageRouteHandler.

    Regards,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • It takes querystring or post variables, stores them into the session or cookies, and redirects to another page. I'm not too familiar with PageRouteHandlers (just what I've read in the past five minutes) but I don't they would work in my situation. Do you agree?
  • Hi Eric,

    There are two methods that you can override in PageRouteHandler to control the HTTP request.

    BuildHandler - The request context.

    GetHttpHandler - Provides the object that processes the request

    If you want you can share your current code so we could see what is the best place to put it inside 4.0.

    Greetings,
    Ivan Dimitrov
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • This is a simplified version of one of my handlers. It stores some values from the querystring and post into the session, then redirects to another page.

    using System.Web;
    using System.Web.SessionState;
     
    namespace MyWebSite.Classes.HttpHandlers
        public class MyHandler : IHttpHandler, IRequiresSessionState
        
            public virtual bool IsReusable
            
                get return false;
            
     
            public void ProcessRequest(HttpContext context)
            
                context.Session["a"] = context.Request.QueryString["a"];
                context.Session["b"] = context.Request.Form["b"];
     
                if (context.Request.QueryString["c"] == "d")
                    context.Response.Redirect("/e", true);
                else
                    context.Response.Redirect("/f", true);
            
        

    Does this look like an application for a PageRouteHandler?

    Thanks,
    Eric
  • Hello Eric,

    I experimented with the handler you implemented below,added some aditional steps and it works fine.

    1) Inherit PageRouteHandler and override GetHttpHandler :

    public class MyPageRouteHandler : PageRouteHandler 
      
          public override IHttpHandler GetHttpHandler(RequestContext requestContext)
          
              return new MyHandler();
          
      

    2) At Bootstrapper.cs, method RegisterRootes, add  to root collection "routes" the page route handler that will process the requests that contain "MyPage" at url.

    routes.Add("MyPage", new Route("MyPage", new MyPageRouteHandler()));

    Note: Be aware that the route handler that first match will serve the request, so MyPageRooteHandler should be added to "routes"  collection before possible other matches.



    Best wishes,
    Milena
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hello Eric,

    Since you don't have direct access to source of Bootsrapper.cs class. Following needs to be done:

    1. Create a class that inherits from PageRouteHandler and inside GetHttpHandler  call your HttpHandler

        public override IHttpHandler GetHttpHandler(RequestContext requestContext)
        
            var node = (SiteMapNode)requestContext.RouteData.DataTokens["SiteMapNode"];
            if (node == null)
                throw new ArgumentException("Invalid request for this route handler. Route data must contain SiteMapNode.");
            //Here goes your condition for custom handler
            if (node.Title == "MyPage")
            
                return new MyHandler();
            
            else
            
                return base.GetHttpHandler(requestContext);
            
        
          
        public static void RegisterType()
        
            ObjectFactory.Container.RegisterType<Telerik.Sitefinity.Web.PageRouteHandler, MyPageRouteHandler>();
        



    2. Then you need to register the custom PageRouteHandler using the application Global.asax file

    protected void Application_Start(object sender, EventArgs e)
        Telerik.Sitefinity.Services.SystemManager.ApplicationStart += new EventHandler<EventArgs>(SystemManager_ApplicationStart);
    void SystemManager_ApplicationStart(object sender, EventArgs e)
        MyPageRouteHandler.RegisterType();



    Regards,
    Milena
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • The RegisterType call gives me a red-squiggly underneat saying it does not have type parameters and is expecting parameters of Type, Type, string, LifetimeManager, and params InjectionMember[]. What should I put here?

    Also, how do I get this to handle a request for a URL that's not in the SF sitemap? With HttpHandlers, I'd put a path of something like "*.mypage" to handle anything with the mypage extension.

    Thanks
  • Hi Eric,

     Sitefinity uses ASP.Net Routing Engine to handle incoming requests. This shouldn’t be preventing you from using mapped HttpHandlers, but it seems some Sitefinity route is catching all requests. We will investigate and fix this as soon as possible.

    In the mean time you could register your own route with the system to handle that specific request. Please disregard the previously suggested steps and follow the once bellow:

    1.       Crate custom route handler like this:

     

    public class MyRouteHandler : IRouteHandler
        public IHttpHandler GetHttpHandler(RequestContext requestContext)
        
            // Return your HttpHandler implementation
            return new MyHttpHandler();
        

    2.       Add Global.asax file to your project and modify it as shown below:

     

    <script runat="server">
      
        void Application_Start(object sender, EventArgs e) 
        
            // Code that runs on application startup
            Telerik.Sitefinity.Abstractions.Bootstrapper.Initialized += new EventHandler<Telerik.Sitefinity.Data.ExecutedEventArgs>(Bootstrapper_Initialized);
        
      
        void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs args)
        
            if (args.CommandName == "RegisterRoutes")
            
                 var routes = (System.Web.Routing.RouteCollection)args.Data;
                routes.Add("MyRoute", new System.Web.Routing.Route("my.page", new MyRouteHandler()));
            
        

     


    NOTE: "my.page" is the URL to which you want to map your HttpHandler. It could be a specific URL or URL pattern. Please see MSDN documentation how to specify URL patterns. Since routes are evaluated in the order they are defined in the route collection, you may need to rearrange them if other route is catching the request before yours. Let me know if you have further questions.

    Best wishes,
    Bob
    the Telerik team

    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Guys,

    I have the same problem with custom routing handler.

    I use Bob's solution from previous post. In the debug mode under VS I can see that handler has been added to routing table, but it did not fire when URL has been requested. It seems, Sitefinity still catch all requests.

    Is there a way to make it work?

    Best regards,
    Anton.
  • Hi Eric,

    Could you please specify the URL pattern that you want to handle?

    You may try to put your route as the first item in the route table but be careful not to catch requests that you do not want to handle.

    Best wishes,
    Bob
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Bob,

    You are right, I just modified my code in Global.asax like this and my handler started to work:
    void Application_Start(object sender, EventArgs e)
        // Code that runs on application startup
        Telerik.Sitefinity.Abstractions.Bootstrapper.Initialized +=
            new EventHandler<Telerik.Sitefinity.Data.ExecutedEventArgs>(Bootstrapper_Initialized);
     
     
    void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs args)
        if (args.CommandName == "RegisterRoutes")
        
            var routes = (System.Web.Routing.RouteCollection)args.Data;
            routes.Insert(0, new System.Web.Routing.Route("catalog/Category.aspx", new Catalog.CatalogRouteHandler()));
        

    Is it possible to specify as virtual path the URL of page from Sitefinity site map?

    For example, I created in Sitefinity ->Pages a new page Catalog with URL ~/catalog. I would like re-route all URLs which started from ~/catalog to this page. There is the following GetHttpHandler method:

    public IHttpHandler GetHttpHandler(RequestContext requestContext)
        var page = BuildManager.CreateInstanceFromVirtualPath("~/catalog", typeof(Page)) as IHttpHandler;
     
        foreach (KeyValuePair<string, object> token in requestContext.RouteData.Values)
        
            requestContext.HttpContext.Items.Add(token.Key, token.Value);
        
     
        return page;

    Unfortunately, I got the following error:

    The file '/catalog' does not exist.
     
    at System.Web.UI.Util.CheckVirtualFileExists(VirtualPath virtualPath)
    at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
    at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
    at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
    at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp)
    at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(String virtualPath, Type requiredBaseType)
    at Catalog.CatalogRouteHandler.GetHttpHandler(RequestContext requestContext) in C:\Inetpub\Sitefinity_4_0\lib\Catalog\CatalogRouteHandler.cs:line 32
    at System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context)
    at System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e)
    at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
    at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

    Is seems, the given virtual path should exist as physical file.
    How can I force to re-route it on page from Sitefinity site map?

    Best regards,
    Anton.
  • Hello Eric,

    You do not need custom HttpHandler to achieve this, if I understand correctly what you need of course.
     
    Please try the following example and let me know if this is what you need.
    1. Create User Control “MyCatalogue.ascx” in the root folder of your site.
    2. Add Label with ID="Category" to the .ascx file.
    3. In the code behind please paste the following code:
      using System;
      using System.IO;
      using Telerik.Sitefinity.Web;
        
      public partial class MyCatalogue : System.Web.UI.UserControl
          protected void Page_Load(object sender, EventArgs e)
          
              var requestContext = this.GetRequestContext();
              var urlParams = (string[])requestContext.RouteData.Values["Params"];
        
              string message;
              if (urlParams != null && urlParams.Length > 0)
                  message = Path.GetFileNameWithoutExtension(urlParams[0]);
              else
                  message = "No category specified.";
              this.Category.Text = message;
          
      NOTE: you need Telerik.Sitefinity.Web namespace in order to see GetRequestContext() extension method.
    4. Save the changes, open your web site in a browser and navigate to ~/Sitefinity/Administration/Settings/Advanced/
    5. Expand the following nodes in the navigation on the right: Toolboxes>Toolboxes>PageControls>Sections>ContentToolboxSection>Tools
    6. In the left pane click “Create new” button.
    7. Fill the input boxes as follows:
      Enabled = true
      ControlType = “~/MyCatalogue.ascx”
      Name = “MyCatalogue”
      Title = “My Catalogue”
    8. Click “Save changes” button
    9. Go to pages and create a page named Catalogue.
    10. Edit the page and drop you new control in a place holder.
    11. Publish the page and then type a URL something like this ~/catalogue/test-category.aspx. You should see “test-category” text on your page.
    I hope this helps. Let me know how it goes.

    Kind regards,
    Bob
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  • Hi Bob,

    Thank you for provided solution! Is seems, this is what I need.

    As far as I understand non-existing parts of URL are added in RouteData, for instance, test-category.aspx.
    I've asked about this behavior in this thread. Radoslav said this is a known bug.

    Maybe I misunderstood something, but I'm wondering will your solution work in the future releases of Sitefinity?
    I'm afraid that the bug will be fixed and this way will not work.

    Best regards,
    Anton.