Click here to Skip to main content
15,886,919 members
Articles / Web Development / ASP.NET

Adding custom HTTP 301 redirects to a webforms application using an HttpModule

Rate me:
Please Sign up or sign in to vote.
4.87/5 (5 votes)
7 Jan 2016CPOL1 min read 7.8K   3  
Article outlining one approach for adding custom HTTP 301 redirects to a webforms application using an HttpModule

I recently needed to retire some old pages on one of my websites but wanted to keep any search engine ranking weight those pages may have accumulated within the site, whilst letting search spiders and visitors alike know that the pages had permanently moved.

The advent of ASP.NET MVC made it easier to generate custom HTTP responses for specific resources on a website without resorting to writing custom modules and handlers to perform those custom actions. If you're looking to implement this sort of functionality on a more traditional webforms site, read on.

There are 2 parts to this technique. The first is to create a custom configuration section inside your Web.config to store the URL mappings and the second is to use an HttpModule to perform the redirection. Let's start by taking a look inside the Web.config file.

<configuration>
  <configSections>
    <section name="redirectMapSection" type="SmileyCreations.Library.Configuration.RedirectMapSection, SmileyCreations.Library"/>
  </configSections>
  <system.web>
    <httpModules>
      <add name="RedirectModule" type="SmileyCreations.Library.RedirectModule, SmileyCreations.Library"/>
    </httpModules>
  </system.web>
  <system.webServer>
    <modules>
      <add name="RedirectModule" type="SmileyCreations.Library.RedirectModule, SmileyCreations.Library"/>
    </modules>
  </system.webServer>
  <redirectMapSection>
    <redirectMappings>
      <add oldUrl="/portfolio/news_cms.aspx" newUrl="/portfolio" />
      <add oldUrl="/portfolio/enquiry_manager.aspx" newUrl="/portfolio" />
      <add oldUrl="/cv.asp" newUrl="/cv.aspx" />
      <add oldUrl="/popup.asp" newUrl="/" />
    </redirectMappings>
  </redirectMapSection>
</configuration>

The key things to note here are that there is an entry defining our custom handler (which we'll get to in a moment) within both system.Web and system.WebServer. This is simply to cover both bases in case the application is deployed to a server running IIS 7 Integrated Mode (system.WebServer section) or IIS6/IIS7 Classic Mode (system.Web section).

Now that we have our configuration defined in the web.Config file, let's have a look at the code. First the configuration code:

public class RedirectMapSection : ConfigurationSection
{
  [ConfigurationProperty("redirectMappings")]
  public RedirectMappings RedirectMappings
  {
    get { return this["redirectMappings"] as RedirectMappings; }
  }

  public static RedirectMapSection GetConfig()
  {
    return ConfigurationManager.GetSection("redirectMapSection") as RedirectMapSection;
  }
}

public class RedirectMappings : ConfigurationElementCollection
{
  public Map this[int index]
  {
    get { return this.BaseGet(index) as Map; }
    set
    {
      if (this.BaseGet(index) != null)
      {
        this.BaseRemoveAt(index);
      }

      base.BaseAdd(index, value);
    }
  }

  protected override ConfigurationElement CreateNewElement()
  {
    return new Map();
  }

  protected override object GetElementKey(ConfigurationElement element)
  {
    return ((Map) element).OldUrl;
  }
}

public class Map : ConfigurationElement
{
  [ConfigurationProperty("oldUrl", DefaultValue = "", IsRequired = false)]
  public string OldUrl
  {
    get { return this["oldUrl"].ToString(); }
    set { this["oldUrl"] = value; }
  }

  [ConfigurationProperty("newUrl", DefaultValue = "", IsRequired = false)]
  public string NewUrl
  {
    get { return this["newUrl"].ToString(); }
    set { this["newUrl"] = value; }
  }
}

And finally, the module itself that does all the work. If the current URL that is requested matches a URL in the config file, the module sends a 301 http header (moved permanently) and sets the location to the new url:

public class RedirectModule : IHttpModule
{
  public void Init(HttpApplication context)
  {
    context.BeginRequest += BeginContextRequest;
  }

  public void Dispose() { }

  private static void BeginContextRequest(object sender, EventArgs e)
  {
    var application = (HttpApplication) sender;
    var request = application.Request;
    var response = application.Response;
    var incomingUrl = request.RawUrl;
    var mappings = RedirectMapSection.GetConfig().RedirectMappings;
    foreach (Map mapping in mappings)
    {
      var oldUrl = mapping.OldUrl;
      var newUrl = mapping.NewUrl;
      if (oldUrl != incomingUrl) continue;
      response.Status = "301 Moved Permanently";
      response.AddHeader("Location", newUrl);
    }
  }
}

View original article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Levelnis Ltd
United Kingdom United Kingdom
Follow along my journey as I create a newsletter about launching websites. Just message me with "I'm in" and I'll add you

Comments and Discussions

 
-- There are no messages in this forum --