Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • RolandWolters 32 posts 32 karma points
    Sep 30, 2009 @ 15:29
    RolandWolters
    0

    301 redirect from non existing url

    For a customer I have build a complete new site in Umbraco. It used to be php and some html. All the old pages are gone. However, most of the old links (very bad SEO, all in root) can be mapped to the new pages in umbraco.

    This is what i came up with:

    • Create custsom 404 handler
    • in the handler coder, check if the url is on the list, then redirect to the new page

    This works BUT.... is HAS to be a 301 redirect.

     

    suggestions? Or back to the original idea: re-create all old pages and write a redirect in the files (300+ pages)

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Sep 30, 2009 @ 15:35
    Dirk De Grave
    0

    Couldn't you do with a http handler and perform a 301 redirect if page url in in list (if that fires before umbraco request handler comes in)?

     

    Hope this helps.

     

    Regards,

    /Dirk

  • RolandWolters 32 posts 32 karma points
    Sep 30, 2009 @ 15:43
    RolandWolters
    0

    how do I do that? I know how to build a httphandler but How do I make it catch the incoming request?

  • Morten Bock 1867 posts 2140 karma points MVP 2x admin c-trib
    Sep 30, 2009 @ 18:26
    Morten Bock
    3

    You can easily do a 301 redirect from a 404 handler. I'm doing it on my blog that I am moving from wordpress to Umbraco.

    Here is my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using umbraco;
    using System.Xml.Linq;
    using System.Web;
    
    namespace MortenBock.Extensions.NotFoundHandlers
    {
        public class LegacyBlogNotFoundHandler : umbraco.interfaces.INotFoundHandler
        {
            private int _redirectID = -1;
    
            public bool CacheUrl
            {
                get { return false; }
            }
    
            public bool Execute(string url)
            {
                //Check if the url matches the old type that ends with .htm
                if (url.EndsWith(".htm"))
                {
                    //Try to locate an umbraco page that fits the requested url
                    XDocument contentDocument = XDocument.Parse(content.Instance.XmlContent.DocumentElement.OuterXml);
                    var q = from c in contentDocument.Descendants("data")
                            where (string)c.Attribute("alias").Value == "blogPostLegacyUrl" && (string)c.Value == "/"+url
                            select c.Parent.Attribute("id");
                    if (q.Count<XAttribute>() > 0)
                    {
                        bool success = int.TryParse(q.ElementAt<XAttribute>(0).Value, out _redirectID);
    
                        //If an umbraco page was found, do a 301 redirect
                        if(success){
                            HttpContext.Current.Response.Status = "301 Moved Permanently";
                            HttpContext.Current.Response.AddHeader("Location",umbraco.library.NiceUrl(_redirectID));
                        }
                        //If not, rutern false to let the next 404 hander try
                        return success;
                    } else {
                        //If not, rutern false to let the next 404 hander try
                        return false;
                    }
                }
                else
                {
                    return false;
                }
            }
    
            public int redirectID
            {
                get { return _redirectID; }
            }
        }
    }
    

     

  • Dirk De Grave 4541 posts 6021 karma points MVP 3x admin c-trib
    Sep 30, 2009 @ 19:10
    Dirk De Grave
    0

    Good approach from Morten, was thinking of setting the status and header on the response object, just wasn't sure if it was the right place here. Apparently it is! Big thumbs up!

     

    Cheers,

    /Dirk

  • RolandWolters 32 posts 32 karma points
    Oct 01, 2009 @ 11:14
    RolandWolters
    0

    This is great! But now the next problem... How do I catch the htm page in my site? Currently it is handled by IIS.

  • RolandWolters 32 posts 32 karma points
    Oct 01, 2009 @ 12:30
    RolandWolters
    0

    damn this is not easy to do in IIS7. It keeps handeling the error BEFORE umbraco can :(

     

    Tips?

  • Douglas Robar 3570 posts 4711 karma points MVP ∞ admin c-trib
    Oct 01, 2009 @ 13:36
    Douglas Robar
    0

    In IIS you need to set .htm (or set a global handler if you like) to be handled by asp.net, just like a .aspx page would be. That should do it.

    cheers,
    doug.

  • Morten Bock 1867 posts 2140 karma points MVP 2x admin c-trib
    Oct 01, 2009 @ 14:46
    Morten Bock
    0

    If you use the integrated pipeline, the it should be handled by default. There is a web.config on codeplex that lets you set up Umbraco to work under integrated pipeline mode.

  • RolandWolters 32 posts 32 karma points
    Oct 01, 2009 @ 17:16
    RolandWolters
    0

    If have downloaded the web.config found here: http://umbraco.codeplex.com/SourceControl/changeset/view/48966#742920

     

    It does work on IIS7, and the custom 404handler i wrote does kick in, but only for aspx files, not htm files. So i think i still must set iis up like douglas wrote. But how?

  • Morten Bock 1867 posts 2140 karma points MVP 2x admin c-trib
    Oct 01, 2009 @ 22:19
    Morten Bock
    0

    Did you set up your site (and app pool) to use Integrated Pipeline mode?

    From: http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/

    "With integrated pipeline, the ASP.NET functionality is fully integrated into the main request processing in IIS, which means that all ASP.NET features are now available for any type of requests. This effectively eliminates the need for the wildcard handler mapping. Now you can use your existing ASP.NET modules and have them applied to all requests."

  • Lee 1130 posts 3088 karma points
    Oct 02, 2009 @ 07:30
    Lee
    0

    Now I have no where near the Umbraco experience as everyone else, so heres two options from me :)

    Option 1

    Not sure if this helps, but I had the same problem with a custom site I developed.  So I created a global.asax file and added the following under Application_Error

        void Application_Error(object sender, EventArgs e){
            // Code that runs when an unhandled error occurs
            Exception ex = new Exception();
            ex = Server.GetLastError();
            if (g.InStr(ex.Message.ToString(), "does not exist") > 0)
            {
              
                // You can 301 redirect here - I run a couple of methods to redirect to the right page, then fall back on a 301 redirect to the home page
              
            }
        }

    From what I have read this isn't ideal, but it got me out of a whole load of problems - Thought you might be able to play with it and come up with somthing

    Options 2

    Install ISAPI rewrite (Free version) and then set the redirects in a mapfile?

    :)

  • RolandWolters 32 posts 32 karma points
    Oct 05, 2009 @ 15:18
    RolandWolters
    0

    still having troubles... Morten, could you please share the web.config you used for this?

  • RolandWolters 32 posts 32 karma points
    Oct 05, 2009 @ 16:12
    RolandWolters
    0

    ok, I got it to work, but not as elegant as i should but i could not let the customer wait any longer.

    This is what I did:

    I created a custom 404page in Umbraco (just like a normal page). In IIS i have set the 404page to this page. On this page in umbraco I put a .net custom control that checks the url. I have a list of old urls that should be redirected to the new. So I check the list, if it is in the list I do the redirect.

    Works, but it is a workaraond. I would rather like to use the umbraco 404 handler mechanism...

    so still I would like to see Morten's webconfig

  • Morten Bock 1867 posts 2140 karma points MVP 2x admin c-trib
    Oct 05, 2009 @ 16:31
    Morten Bock
    0

    Hi Roland

    The web.config I used is the one located here:

    http://umbraco.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=23321#DownloadId=70203

    Only thing I changed is the connectionstring. Did you go into your IIS manager and select the Integrated Pipeline mode for your app pool? You need to do that to use the web.config file...

  • arviman 71 posts 92 karma points
    Jun 11, 2010 @ 22:32
    arviman
    0

    Morten, How did you connect your rewrite module to the web.config? I was under the impression that you have to let IIS 7 know about your url rewriting module.

    I tried adding <add name="MyUrlRewrite" type="MyNamespace.MyModule.Redirect_Handler, MyNamespace.MyModule" preCondition="" /> inside the <system.webServer> <modules> .. </modules> </system.webServer> tags, but IIS somehow isn't able to find my module.

    I even used .net reflector to make sure the right "MyNamespace.MyModule" was present in the dll in my bin folder.. Any ideas on what is to be done? Perhaps i need to add this information inside <system.web> <httpModules>, but I thought that was only for IIS 6.

     

  • Morten Bock 1867 posts 2140 karma points MVP 2x admin c-trib
    Jun 11, 2010 @ 23:08
    Morten Bock
    0

    I did not write a module. I implemented the inotfoundhandler interface from umbraco, and added my class to the /config/404handlers.config file.

    If your module is not running, you might want to google a bit for the runallmanagedmodulesforallrequests attribute. It seems to help sometimes, in order to get modules to run for all requests, regardless of extension.

  • arviman 71 posts 92 karma points
    Jun 15, 2010 @ 04:11
    arviman
    0

    Great suggestion morten.  Meanwhile what i ended up doing was to create a branch of the umbraco source, where I modified the requestmodule.cs inside the presentation module. This works well for me.

    protected void Application_BeginRequest(Object sender, EventArgs e)
            {
                HttpApplication app = (HttpApplication)sender;

                //first time init, starts timers, and sets httpContext
                InitializeApplication(app);

                // grab the original url before anything modifies  it
                HttpContext httpContext = mApp.Context;
                httpContext.Items[ORIGINAL_URL_CXT_KEY] = rewrite404Url(httpContext.Request.Url.AbsolutePath, httpContext.Request.Url.Query, false);

                // create the Umbraco context
                UmbracoContext.Current = new UmbracoContext(httpContext);
                string path = httpContext.Request.Path;
                string newURL = "";
                //return 301 (for google) if URL is old page (info. stored in custom table)
                if (DBHelper.getURLToRewrite(path.Length > 2 ? path.Substring(1):"", out newURL))
                {
    //perform 301 redirect
                    httpContext.Response.Clear();                       
                    httpContext.Response.Status = "301 Moved Permanently";
                    httpContext.Response.AddHeader("Location", newURL);    
                  
                }

                // rewrite will happen after authorization
            }
Please Sign in or register to post replies

Write your reply to:

Draft