Thursday, March 24, 2011

Sitefinity 3.7 - Custom Url Rewrite Module

In our application we need to redirect the user from a old website page to the new website page. Sitefinity has built in Module to rewrite the url. The below link clearly explains it.

http://www.sitefinitywatch.com/blog/09-01-08/URL_Rewriting_with_Sitefinity_s_AdvancedUrlRewriter.aspx

In our application we have plenty of  URLS to rewrite and we dont want to put all these stuff in web.config. So We have created a Custom Module to rewrite the URLs. This module reads the xml file (which contains a set of url rewrites and the format is same as url rewrites defined in the web.config.) and rewrites the URL.

In our application we have two xml files, one is for pdf documents and the other is for page re-directions.

Code :

App_Code/RedirectModule.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Configuration;
using System.Text.RegularExpressions;


namespace Ramp.UrlRedirect
{

/// <summary>
/// Summary description for RedirectModule
/// </summary>
public class RedirectModule : IHttpModule
{
public void Init(HttpApplication app)
{
app.BeginRequest += new EventHandler(OnBeginRequest);
}

private void OnBeginRequest(object src, EventArgs e)
{
HttpApplication app = src as HttpApplication;
string requestedUrl = app.Request.Url.AbsolutePath.ToLower();
if (requestedUrl == "/index.html")
{
try
{
app.Response.StatusCode = 301; // make a permanent redirect
app.Response.AddHeader("Location", "/");
app.Response.End();
return;
}
catch { }
}

if (!requestedUrl.Contains(ConfigurationManager.AppSettings["SearchResultsPage"].ToLower()))
{

DataSet dataset = new DataSet();

Regex pdfRegx = new Regex("(.pdf)$", RegexOptions.IgnoreCase);

if (pdfRegx.IsMatch(requestedUrl))
{
dataset.ReadXml(app.Server.MapPath("~/Res/Redirections/doc_redirections.xml"));
}
else
{
dataset.ReadXml(app.Server.MapPath("~/Res/Redirections/page_redirections.xml"));
}


for (int i = 0; i < dataset.Tables[0].Rows.Count; i++)
{
try
{
string sourceUrl = dataset.Tables[0].Rows[i].ItemArray[0].ToString();
string targetUrl = dataset.Tables[0].Rows[i].ItemArray[1].ToString();

Regex targetRegex = new Regex(targetUrl, RegexOptions.IgnoreCase);

if (targetRegex.IsMatch(requestedUrl))
{
return;
}

Regex sourceRegex = new Regex(sourceUrl, RegexOptions.IgnoreCase);
if (sourceRegex.IsMatch(requestedUrl))
{
string destinationUrl = sourceRegex.Replace(requestedUrl, targetUrl, 1);
app.Response.StatusCode = 301; // make a permanent redirect
app.Response.AddHeader("Location", destinationUrl + app.Request.Url.Query);
app.Response.End();
break;
}
}
catch { }
}
}

}

public void Dispose()
{
}
}
}

web.config changes
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<remove name="ScriptModule" />
<remove name="Cms" />
<!--<remove name="LibraryModule"/>-->
<remove name="RadUploadModule" />
<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add name="Cms" type="Telerik.Cms.Web.CmsHttpModuleUrlRewrite, Telerik.Cms" />
<add name="RedirectModule" type="Ramp.UrlRedirect.RedirectModule, App_Code" />

<!-- Http Module for extension mappings in Library module.-->
<!--<add name="LibraryModule" type="Telerik.Libraries.LibraryHttpModule, Telerik.Libraries"/>-->
<add name="RadUploadModule" preCondition="managedHandler" type="Telerik.Web.UI.RadUploadHttpModule, Telerik.Web.UI" />
</modules>
...............................
.................................

Xml file URL rewrite element format

<?xml version="1.0" standalone="yes"?>
<urlrewrites>
<rule>
<url>subscribe.html</url>
<rewrite>subscribe.aspx</rewrite>
</rule>
<rule>

    . . . . . . .

</rule>
.. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
</urlrewrites>