Question? How to integrate URL Rerouting with SiteFinity V

Posted by Community Admin on 04-Aug-2018 17:31

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

All Replies

Posted by Community Admin on 22-Jan-2012 00:00
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
Posted by Community Admin on 22-Jan-2012 00:00
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"


Posted by Community Admin on 23-Jan-2012 00:00
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.


 









Posted by Community Admin on 29-Jan-2012 00:00
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);

Posted by Community Admin on 01-Feb-2012 00:00
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;

This thread is closed