+1-888-365-2779
Try Now
More in this section

Forums / Bugs & Issues / Question? How to integrate URL Rerouting with SiteFinity Virtual folder structure Version 4.3.1885.0

Question? How to integrate URL Rerouting with SiteFinity Virtual folder structure Version 4.3.1885.0

5 posts, 0 answered
  1. Doug Lubey
    Doug Lubey avatar
    31 posts
    Registered:
    17 Apr 2010
    22 Jan 2012
    Link to this post
    Summary: I would like to integrate the control I built to handle my details page with the Sitefinity virtual folder structure. 

    Why? Becuase I want to use all of SiteFinity Magic (controls and architecture); so I can have
    consistency of the approach I use for programming the website.

    I guess one option would be:  
    Use one of SiteFinity master pages and keep the page
    externallized from sitefinity (but this is not the consistent approach). 
    And our web designer would not be able to adjust the "SCREEN"


    What was I already able to accomplish:
    I was able to get URL ReRouting to work in a standard asp.net website;
    in the sitefinity site using a standard aspx.  

    This is what I was able to get working:
    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/bugs-issues/url-rerouting-does-not-appear-to-work-in-sitefinity-version-4-3-1885-0.aspx


    What I would like to do:

    "Training/available-courses/Details/{CourseId}/{CourseName}"

    , "~/UserControls/CourseDetails/CourseDetails.ascx"


    Where "Training" is a sitefinity virtual folder
    Where "Available-Courses"  is a Virtual folder
    Where "Details" is a sitefinity virtual page (which contains the control)

    Example URL would then look like this:
    Training/available-courses/Details/234/MyCourseName


    but the error I get is PAGE NOT FOUND
     

    Server Error in '/' Application.

    Page not found

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Web.HttpException: Page not found

    Source Error:

    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

    Stack Trace:

    [HttpException (0x80004005): Page not found] Telerik.Sitefinity.Web.PageRouteHandler.handler_PreRenderComplete(Object sender, EventArgs e) +1132 System.EventHandler.Invoke(Object sender, EventArgs e) +0 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +4543 

    thanks,

    Doug Lubey of Louisiana


    =======================
    I attempted to Include an additional URL in the SiteFinity Interface.
    But the Form validation stopped me from adding Reroute variables
    ~/Training/courses/Details/{CourseId}/{CourseName}
    See the attachment for more details

    search engine reference:Telerik.Sitefinity.Web.PageRouteHandler.handler_PreRenderComplete
  2. Doug Lubey
    Doug Lubey avatar
    31 posts
    Registered:
    17 Apr 2010
    22 Jan 2012
    Link to this post
    I also employed the method which is described in this article at the bottom of this thread. Which is basically the same thing as I described above.   But I wanted to be 100% sure I was not missing something.
    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/general-discussions/httphandler-not-working.aspx


    Also to note:  It appears others have this same problem and it was reported as a bug; but it is reporting as fixed. 
    This should be FLAGGED AS "NOT FIXED" .http://www.telerik.com/support/pits.aspx#/public/sitefinity/4964

    TELERIK posted a work-around to "INTERCEPT" the request.  But this is still not URL-REROUTING.
    Here is the work-around...With out allowing use to use URL-REROUTING PARAMETERS.
    http://www.sitefinity.com/devnet/forums/sitefinity-4-x/developing-with-sitefinity/url-routing.aspx

    Question to Telerik?
    How can you really do "URL re routing" while still using variables?

    see my next comment on the implementation of a "WORK-AROUND"


  3. Doug Lubey
    Doug Lubey avatar
    31 posts
    Registered:
    17 Apr 2010
    23 Jan 2012
    Link to this post
    Wow...SiteFinity ReRouting is Hard and I believe not very good with performance (at least the way I finally  did it).   Their has to be a better way; expecially since .net 4.0 makes it so easy out of the box. 
    Telerik; it would be nice if you could just add the allowance in page settings for the UI.
    ALLOW MULTIPLE URLS for this PAGE (and allow URL Parameters)
    ~/Training/courses/Details/{CourseId}/{CourseName}
    It just makes sense.

    Anyhow; this is my implementation which I will use for now;  Telerik if can suggest something better; please do.

    PROOF OF CONCEPT;
    Step1> USe the standard directions for creating a Page and inserting a Customized user control
    (see other urls on how to do this)
    Step2> PARSE THE URL in the control (I simply wanted only a courseid; and it was numeric)
    // CODE IN THE CONTROL
        private void ParseMyUrl()
        {
            lblTroubleShooting.Text = "";
            long locCourseId = 0;
            try
            {
                string locUrlToSplit = HttpContext.Current.Request.Url.AbsolutePath;
                string[] urlStringParts = locUrlToSplit.Split('/');
                for (int i = 0; i < urlStringParts.Length; i++)
                {
                    if (long.TryParse(urlStringParts[i], out locCourseId))
                    {
                        lblTroubleShooting.Text += "COURSEID="+urlStringParts[i] +"/";
                        i = urlStringParts.Length + 1;
                    } else {
                        lblTroubleShooting.Text += urlStringParts[i] +"/";
                    }
                }
            }
            catch (Exception ex)
            {
                string locException = ex.ToString();
                lblTroubleShooting.Text += "<br/>Exception Occurred: Requested URL Could not be parsed<br/>";
                lblTroubleShooting.Text += "<br/>" + ex.Message.ToString();
            }
        }

     STEP3>  Build  a CLASS FILE (which resembles this)

    // ENTIRE CLASS FILE
    using System;
    using System.Globalization;
    using System.Web;
    using Telerik.Microsoft.Practices.Unity;
    using Telerik.Sitefinity.Abstractions;
    using Telerik.Sitefinity.Configuration;
    using Telerik.Sitefinity.Localization.UrlLocalizationStrategies;
    using Telerik.Sitefinity.Modules.Pages.Configuration;
    using Telerik.Sitefinity.Pages.Model;
    using Telerik.Sitefinity.Services;
    using Telerik.Sitefinity.Web;
     
     
     
    namespace DJLSitefinityWebApp
    {
     
        public class CustomSitefinityRoute : SitefinityRoute
        {
            public override System.Web.Routing.RouteData GetRouteData(HttpContextBase httpContext)
            {
                //get the path from the httpContext variable and parse it
                var virtuallPath = this.GetVirtualPathInternal(httpContext);
                //where dougtestcoursedetails is the Name of the Virtual Page in SiteFinity
                if (virtuallPath.Contains("dougtestcoursedetails"))
                { SEE CORRECTION IN THE NEXT POST FOR THIS(needs an if statement)
                    //parse the acutal path to find the PageSiteNode from the sitemap provider
                    var sitemapProvider = this.GetSiteMapProvider();
                    if (sitemapProvider == null)
                        return null;
                    bool isAdditional;
                    string[] pars;
                    //where Training/dougtestcoursedetails is the Virtual Path in SiteFinity
                    var node = sitemapProvider.FindSiteMapNode("Training/dougtestcoursedetails", false, out isAdditional, out pars);
                    if (node != null)
                        return this.GetRouteDataInternal(pars, httpContext.Request.QueryString, node);
                }
                return base.GetRouteData(httpContext);
            }
     
     
     
            public static void RegisterType()
            {
                ObjectFactory.Container.RegisterType<SitefinityRoute, CustomSitefinityRoute>();
            }
        }
     
    }

    Step 4>// ALTER THE GLOBAL.ASAX

    //Application on Start
        void Application_Start(object sender, EventArgs e)
        {
            Telerik.Sitefinity.Abstractions.Bootstrapper.Initialized +=
                new EventHandler<Telerik.Sitefinity.Data.ExecutedEventArgs>(Bootstrapper_Initialized);
        }
     
    // CALLING CODE:
        void Bootstrapper_Initialized(object sender, Telerik.Sitefinity.Data.ExecutedEventArgs args)
        {
            if (args.CommandName == "RegisterRoutes")
            {
                //YES: I can intercept the web request; but it is not "REROUTING";  it is intercepting
                System.Web.Routing.RouteTable.Routes.Insert(0, new DJLSitefinityWebApp.CustomSitefinityRoute()); 
            }
        }

    I wish I could find a better way; expecially since .net 4.0 makes it so easy to do it;
    But it is; what is is.  If Telerik could shed some light on this with "SUGGESTED WAY";
    it would be great.


     









  4. Doug Lubey
    Doug Lubey avatar
    31 posts
    Registered:
    17 Apr 2010
    29 Jan 2012
    Link to this post
    OK found a bug in the above code:  The Page_load event would execute multiple times.  Why; becuase every js and css file which was used on the master page was considered in the process. So for a given page; this means if thier is 10 js files; this code would be called 11x times. LIKE I SAID ABOVE; TELERIK WOULD BE NICE IF THEY CHIMED IN AND TOLD US HOW TO REALLY DO RE-ROUTING INSIDE THEIR FRAMEWORK.

    but for what it is: I have included the new script
    public override System.Web.Routing.RouteData GetRouteData(HttpContextBase httpContext)
    {
        //get the path from the httpContext variable and parse it
        var virtuallPath = this.GetVirtualPathInternal(httpContext);
        //where dougtestcoursedetails is the Name of the Virtual Page in SiteFinity
        if (virtuallPath.Contains(_privCourseDetailsPath))
        {
            if (!(virtuallPath.Contains(".css")) && !(virtuallPath.Contains(".js")))
            {
                //parse the acutal path to find the PageSiteNode from the sitemap provider
                var sitemapProvider = this.GetSiteMapProvider();
                if (sitemapProvider == null)
                    return null;
                bool isAdditional;
                string[] pars;
                //where Training/dougtestcoursedetails is the Virtual Path in SiteFinity
                var node = sitemapProvider.FindSiteMapNode(_privCourseDetailsPath, false, out isAdditional, out pars);
                if (node != null)
                    return this.GetRouteDataInternal(pars, httpContext.Request.QueryString, node);
            }
        }
        return base.GetRouteData(httpContext);
    }

  5. Viktor
    Viktor avatar
    22 posts
    Registered:
    01 Nov 2011
    01 Feb 2012
    Link to this post
    Hi,

    We are faced with a very similar issue, but I'm not sure how well your code is going to work. By simply overriding the GetRouteData we are not doing all the checks that Sitefinity does. Additionally we need to make sure that this works in each culture. This becomes a problem as URLs are likely to differ from one culture to another.

    This is the SF implementation:

    if (!this.VerifyRequest(httpContext))
    {
        return null;
    }
    string virtualPathInternal = this.GetVirtualPathInternal(httpContext);
    if (virtualPathInternal != null)
    {
        SiteMapBase siteMapProvider = this.GetSiteMapProvider();
        if (siteMapProvider == null)
        {
            return null;
        }
        if (virtualPathInternal.EndsWith("Telerik.Web.UI.SpellCheckHandler.axd") || virtualPathInternal.EndsWith("Telerik.Web.UI.DialogHandler.aspx") || virtualPathInternal.EndsWith("ChartImage.axd"))
        {
            return null;
        }
        string text = this.ProcessLanguage(virtualPathInternal);
        bool flag;
        string[] array;
        System.Web.SiteMapNode siteMapNode = siteMapProvider.FindSiteMapNode(text, false, out flag, out array);
        if (siteMapNode != null && siteMapProvider.IsMultilingual && !ControlExtensions.IsBackend())
        {
            System.Globalization.CultureInfo cultureInfo = System.Globalization.CultureInfo.CurrentUICulture;
            if (flag)
            {
                System.Globalization.CultureInfo cultureInfo2 = SystemManager.CurrentHttpContext.Items["AdditionalUrlCulture"] as System.Globalization.CultureInfo;
                if (cultureInfo2 != null)
                {
                    cultureInfo = cultureInfo2;
                }
            }
            System.Web.SiteMapNode siteMapNode2 = siteMapProvider.FindSiteMapNodeForSpecificLanguage(siteMapNode, cultureInfo);
            siteMapNode = siteMapNode2;
        }
        if (siteMapNode != null)
        {
            PageSiteNode pageSiteNode = (PageSiteNode)siteMapNode;
            if (this.ProcessRedirects(httpContext, ref pageSiteNode, flag, array) || !this.CheckSecurity(httpContext, pageSiteNode))
            {
                return null;
            }
            this.SetRequestVariables(httpContext, siteMapProvider, pageSiteNode);
            RouteData routeData = this.TryGetSpecialRouteData(httpContext, pageSiteNode, array);
            if (routeData != null)
            {
                return routeData;
            }
            pageSiteNode.EnsurePageDataLoaded();
            if (!pageSiteNode.IsPublished(null))
            {
                return null;
            }
            if (!Config.Get<PagesConfig>().EnableBackwardCompatabilityForPagesUrls && !pageSiteNode.IsBackend && !pageSiteNode.AllowParametersValidation && array != null && array.Length > 0)
            {
                return null;
            }
            return this.GetRouteDataInternal(array, httpContext.Request.QueryString, pageSiteNode);
        }
        else
        {
            if (string.IsNullOrEmpty(text) || text.Equals("/"))
            {
                return new RouteData(this, new UnderConstructionRouteHandler());
            }
        }
    }
    return null;

5 posts, 0 answered