Want to follow this site? Here's the RSS feed.

Fundamentals of Themelia - Redirects

Tuesday, September 9, 2008

This documentation has been updated for Themelia Framework 2.0 Beta 5.

Sometimes you want to handle a route with an HTTP handler, sometimes you want to do an alias, but other times you may want to just a simple redirect.  Maybe something moved or you just want a "shrink" URL on your web site so others can find a link faster.  Fortunately, Themelia provides the ability to setup redirects in a variety of different ways.  Further, to make things simple, redirects are configured very similarly to aliases.

The first way to setup a redirect is the two-part model of setting up a redirect handler and writing a redirect entry:

<themelia.web>
  <webDomains>
    <add>
      <handlers>
        <add matchType="pathStartsWith" name="Redirect" text="jd8" />
      </handlers>
      <redirects>
        <add key="jd8" destination="http://www.somedudeswebsite.com/this/is/a/really/long/url/no/one/will/remember" />
      </redirects>
    </add>
  </webDomains>
</themelia.web>

This configuration should be nearly self explanatory: your handler routes all paths that start with "jd8" to the "Redirect" handler.  When the "Redirect" handler loads, it knows to look in it's area (<redirects>) for the appropriate information.

As is explained in Like with basic HTTP routing, handlers are loaded based on rules of specificity.  Also, as with page aliases, once the correct handler is matches, then the appropriate redirect is loaded based upon the key of the redirect which must match the text of the handler.

Initialization Parameters

Another option you have is to use Themelia initialization parameters.  Various features in Themelia support this and while the mechanics of them are beyond the scope of the current discussion, using them for redirects is very simple.  The basic idea is that instead of doing a two-part registration of a redirect, you tell the handler itself some information that will be passed to the handler.  As you will see form the following example, the initialization parameter syntax for redirects makes Themelia redirects even simpler to work with:

<themelia.web>
  <webDomains>
    <add>
      <handlers>
        <add matchType="pathStartsWith" name="Redirect" text="jd8">
          <parameters>
            <add name="Destination" value="http://www.somedudeswebsite.com/this/is/a/really/long/url/no/one/will/remember" />
          </parameters>
        </add>
      </handlers>
    </add>
  </webDomains>
</themelia.web>

All you need to do is set the destination parameter to the appropriate URL and you're done.

Redirect Fall Through Processor

Say you had an entire section of your web site that you would like to use for nothing but redirects.  Perhaps you would like to setup a /shrink/ path on your web site to allow easy to remember URLs for your company or family.  If you understand the fundamentals of Themelia, your mind should lean towards using a web domain with a fall through processor for redirects.  Well, guess what... Themelia ships with a fall through processor called the RedirectFallThroughProcessor.  This scenario is easily created by the following sample syntax:

<themelia.web>
  <webDomains>
    <add name="shrink" path="shrink">
      <fallThroughProcessors>
        <add type="RedirectFallThroughProcessor" />
      </fallThroughProcessors>
      <redirects>
        <add key="jd8" destination="http://www.somedudeswebsite.com/this/is/a/really/long/url/no/one/will/remember" />
        <add key="f93" destination="http://www.somedudeswebsite.com/this/is/another/really/long/url/no/one/will/remember" />
        <add key="d8l" destination="http://www.somedudeswebsite.com/this/is/yet/another/really/long/url/no/one/will/remember" />
      </redirects>
    </add>
  </webDomains>
</themelia.web>

Now your people can simply go to http://www.yourwebsite.com/shrink/jd8, http://www.yourwebsite.com/shrink/jd8, and http://www.yourwebsite.com/shrink/jd8 to access the long URLs.

Custom Redirecting

If you are rather ambitious, perhaps you would like a more powerful mechanism for dynamically storing shrunk URLs.  Using Themelia this is also incredibly simple.  Though we could store out shrunk URLs anywhere, especially in a database, for our example, lets store them in a plain old XML file that looks like the following redirect.xml file:

<shrink>
  <url matchType="webDomainPathStartsWith" alias="dev" target="http://www.codeplex.com/devserver/" />
  <url matchType="webDomainPathStartsWith" alias="min" target="http://www.codeplex.com/minima/" />
</shrink>

Now what we can do is create a custom fall through processor which catches all requests in a web domain and matches them against our XML file (of course, in reality we would use a database with caching with properly set dependencies, but for the same of our example, XML without locking is easier to demonstrate):

using System;
//+
namespace Sample.Web.Routing
{
    public class CustomRedirectFallthroughProcessor : Themelia.Web.Routing.FallThroughProcessorBase
    {
        //- @GetHandler -//
        public override System.Web.IHttpHandler GetHandler(System.Web.HttpContext context, String requestType, String virtualPath, String path, params Object[] parameterArray)
        {
            System.IO.StreamReader reader = new System.IO.StreamReader(@"redirect.xml");
            System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(reader);
            while (xmlReader.Read())
            {
                if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
                {
                    String matchType = xmlReader.GetAttribute("matchType");
                    String alias = xmlReader.GetAttribute("alias");
                    String target = xmlReader.GetAttribute("target");
                    //+
                    if (Themelia.Web.Routing.RouteMatcher.Match(matchType, alias))
                    {
                        Themelia.Web.Http.Redirect(target);
                    }
                }
            }
            //+
            return null;
        }
    }
}

Now all we have to do is register our fall through processor in our "shrink" web domain and viola, we have our own URL shrink server:

<themelia.web>
  <webDomains>
    <add name="shrink" path="shrink">
      <fallThroughProcessors>
        <add type="Sample.Web.Routing.CustomRedirectFallthroughProcessor, Sample.Web" />
      </fallThroughProcessors>
    </add>
  </webDomains>
</themelia.web>

With this example www.yourdomain.com/shrink/dev goes to http://www.codeplex.com/devserver  and www.yourdomain.com/shrink/min goes to http://www.codeplex.com/minima.  Given other matchTypes or different web domains, you can match different types of patterns as well.

That's really all there is to it.  No longer do you need to rely on an external service for all your URLs and no more importing and updating URLs.  If your data were in a centralized database, everything could be connected to that centralized location.  Not only that, but you would, of course, split this up into various web domains to allow each web domain to have its own shrunk URLs.

404 Replacement

This isn't always a good idea.  In fact, it's rarely a good idea.  However, for internal applications, it could be rather helpful.  Sometimes you don't want 404 messages on your application at all (on a web site, you normally want to leave them.) In these, situations perhaps you want a redirect to another location when an improper link is accessed.  The Themelia configuration for this is simple:

<themelia.web>
  <webDomains>
    <add>
      <fallThroughProcessors>
        <add type="RedirectFallThroughProcessor" />
      </fallThroughProcessors>
      <redirects>
        <add match="" destination="/" />
      </redirects>
    </add>
  </webDomains>
</themelia.web>

In short, we have the redirect fall through processor with a catch all redirect sending the user to the root.  This will effectively send all access to non-registered areas of your application to the root.

Links

Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.

Powered by the Minima Blog Engine 3.1 and Squid Micro-Blogging Library.

Built on Themelia Framework 2.0

Developed using NetFXHarmonics DevServer 1.1.

(all of which are NetFXHarmonics products created by David Betz)

Mini-icons are part of the Silk Icons set of icons at famfamfam.com