Url Routing in Asp.Net Web Forms


One of the coolest features in Asp.Net 3.5  SP1 is web form URL  Routing (thanks for asp.net team). URL routing would really help in Search Engine based websites. You can download the article source code from the bottom of the page

How to Implement URL Routing

1) Create a web site using VS 2008 C#.
2) Right click the project and add reference to System.Web.Routing dll (make sure you have Asp.Net 3.5 Service Pack 1 installed in your machine)
3) Add the following lines to web.config file

Web.conifg  Configuration

The application resides in IIS 6.0 and IIS 7.0 you should  add the UrlRoutingModule class to the httpModules

<httpModules>
<add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35″ />
</httpModules>

For IIS 7.0 only

<system.webServer>
<modules>
<remove name=”UrlRoutingModule” />
<add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35″ />
</modules>
<handlers>
<add name=”UrlRoutingHandler” preCondition=”integratedMode” verb=”*” path=”UrlRouting.axd” type=”System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” />
</handlers>
</system.webServer>

Global.asax file Configuration

Add Import directive to Import System.Web.Routing name space

<%@ Import Namespace=”System.Web.Routing” %>

Register Routes in Application_Start method

void Application_Start(object sender, EventArgs e)
{
RegisterRoutes(RouteTable.Routes);
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.Add(“MemberList”, new Route
(
“member/{name}”,
new MemberRouteHandler(“~/member/userlist.aspx”)
));
}

The first parameter member/{name} which denote the url structure, here the url which starts /member/{name} (ex : /member/deepu/) will point physically to the following path ~/member/userlist.aspx

The above RegisterRoutes method register a class called MemberRouteHandler.cs

using System.Web.Compilation;
using System.Web.UI;
using System.Web;
using System.Web.Routing;

public interface IRoutablePage
{
RequestContext RequestContext { set; }
}

public class MemberRouteHandler : IRouteHandler
{
public MemberRouteHandler(string virtualPath)
{
this.VirtualPath = virtualPath;
}

public string VirtualPath { get; private set; }

public IHttpHandler GetHttpHandler(RequestContext
requestContext)
{
var page = BuildManager.CreateInstanceFromVirtualPath
(VirtualPath, typeof(Page)) as IHttpHandler;

if (page != null)
{
var routablePage = page as IRoutablePage;

if (routablePage != null) routablePage.RequestContext = requestContext;
}

return page;
}

}

Now we can create the Aspx pages to test the Routing. We need to create two aspx files member listing file and detail file.

Create a folder called member in root of the site.  (you can keep any name but make sure you have to change in global.asx file in Route constructor “member/{name}”)

Create a aspx page inside the member folder called default.aspx

This page will have a list of Members in Tabular format. I am going to use asp.net List view control to achieve this.

<form id=”form1″ runat=”server”>

<asp:ListView ID=”lvUserList” runat=”server”>
<LayoutTemplate>
<table width=”50%” style=”background-color: lightgrey;” cellpadding=”2″ cellspacing=”1″
border=”0″>
<tr style=”background-color: white”>
<td width=”100″ align=”center”>
Member ID
</td>
<td align=”center”>
Name
</td>
<td width=”75″ align=”center”>
Age
</td>
<td width=”50″>
</td>
</tr>
<asp:PlaceHolder ID=”itemPlaceholder” runat=”server” />
</table>
</LayoutTemplate>
<ItemTemplate>
<tr style=”background-color: white”>
<td align=”center”>
<asp:Label ID=”lab” Text='<%# DataBinder.Eval(Container.DataItem, “MemberID”)%>’
runat=”server” />
</td>
<td>
<asp:Label ID=”Label1″ Text='<%# DataBinder.Eval(Container.DataItem, “Name”)%>’ runat=”server” />
</td>
<td align=”center”>
<asp:Label ID=”Label2″ Text='<%# DataBinder.Eval(Container.DataItem, “Age”)%>’ runat=”server” />
</td>
<td align=”center”>
<a href=”<%= ResolveUrl(“~/member/”)%><%# DataBinder.Eval(Container.DataItem, “Name”)%>”>
Detail</a>
</td>
</tr>
</ItemTemplate>
<ItemSeparatorTemplate>
<br />
</ItemSeparatorTemplate>
</asp:ListView>
</form>

Above markup will have a list of members and the hyper link column you can see the url structure which is defined in gloabal.asax file RouteMethod pattern.

<a href=”<%= ResolveUrl(“~/member/”)%><%# DataBinder.Eval(Container.DataItem, “Name”)%>”>

ResolveUrl(“~/member/”) = point to member folder from the root
<%# DataBinder.Eval(Container.DataItem, “Name”)%> = second parameter Member Name.  [for ex: ResolveUrl(“~/member/deepu”) ]

Default.aspx.cs code behind

using System;
using System.Collections.Generic;
using System.Linq;

public partial class Memeber
{
public int MemberID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindUsers();
}
}

void BindUsers()
{

var items = new List<Memeber>()
{
new Memeber {MemberID = 1,Name = “Arjun”, Age = 1},
new Memeber {MemberID = 2,Name = “Deepu”, Age = 29},
new Memeber {MemberID = 3,Name = “Rakesh”, Age = 31},
new Memeber {MemberID = 4,Name = “Abhilash”, Age = 21},
};

lvUserList.DataSource = items.ToList();
lvUserList.DataBind();
}

We have completed the listing page. The next page will be the detail page which will be rendering the member name from the URL routing.

userlist.aspx page Markup

<form id=”form1″ runat=”server”>
<div>
<asp:Label ID=”labMemberName” runat=”server” />
</div>
</form>

In the code behind file for the detail page you must implement IRoutablePage interface class.

Code behind :

public partial class user_userlist : System.Web.UI.Page, IRoutablePage
{
public System.Web.Routing.RequestContext requestContext;

#region IRoutablePage Members
public System.Web.Routing.RequestContext RequestContext
{
set { requestContext = value; }
}
#endregion
protected object RouteValue(string key)
{
if (requestContext != null && requestContext.RouteData != null)
{
return requestContext.RouteData.Values[key];
}
return null;
}

protected void Page_Load(object sender, EventArgs e)
{
object memberName = RouteValue(“name”);
if (memberName != null)
{
labMemberName.Text = memberName.ToString();
}
}
}

Note : If you are implementing url routing in GoDaddy server and you are using Session variables in the routing pages you should add Session module (manually)

<httpModules>
<add name=”Session” type=”System.Web.SessionState.SessionStateModule”/>
<add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35″ />
</httpModules>

<system.webServer>
<modules>
<remove name=”Session” />
<add name=”Session” type=”System.Web.SessionState.SessionStateModule”/>
<remove name=”UrlRoutingModule” />
<add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35″ />
</modules>
<handlers>
<add name=”UrlRoutingHandler” preCondition=”integratedMode” verb=”*” path=”UrlRouting.axd” type=”System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” />
</handlers>
</system.webServer>

Note : Always use ResolveUrl  for images OR css file or links to get the virtual path of the folder from the web site root  in the routing pages.
for ex :  [ ResolveUrl (“~/images/logo.jpg”) ]

You can download the entire article from here

or copy paste this url  http://www.4shared.com/file/230713773/954be86b/UrlRouting.html  in to your browser.

Hope this help and If you have any comments, please feel free to write your feedback.

Thanks
Deepu

<system.webServer>
<modules>
<remove name=”Session” />
<add name=”Session” type=”System.Web.SessionState.SessionStateModule”/>
<remove name=”UrlRoutingModule” />
<add name=”UrlRoutingModule” type=”System.Web.Routing.UrlRoutingModule,System.Web.Routing,Version=3.5.0.0,Culture=neutral,PublicKeyToken=31BF3856AD364E35″ />
</modules>
<handlers>
<add name=”UrlRoutingHandler” preCondition=”integratedMode” verb=”*” path=”UrlRouting.axd” type=”System.Web.HttpForbiddenHandler, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” />
</handlers>
</system.webServer>