URL Rooting in ASP.NET (Web Forms)

If you are an ASP.NET MVC developer, you will certainly be aware of its default URL Routing behavior, where if for example you were to display a View named “Index” that was relying in a controller named “ProductsController”, you could request it with the following URL:

/products/index

On the other side, if you had a simple ASP.NET Web Forms project and not an MVC one, you would have to request the full path of the page that you wanted to display.

/full_path/index.aspx

You must know though, that it’s possible to support MVC like URL Routing in Web Forms too. This post will show you how to create Hackable URLs in your Web Forms project. To start with, open Visual Studio and create a new Empty ASP.NET Web Application project. Create a new WebForm named “Default.aspx” page in the root directory and paste the following contents.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AspNetUrlRouting.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Default.aspx</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <h1>This is the Default.aspx</h1>
    </div>
    </form>
</body>
</html>

It’s a simple page with an h1 tag to display the page’s name. All the pages that we are going to create will display this information and only. Create a new folder named “Univercity” and add a new Web Form inside it, named “Students.aspx”. Add again an h1 element to display the path and the file name of the new page.

<h1>This is the Univercity/Students.aspx</h1>

By now, your project’s structure should look like this.
web-forms-urlrouting_01
You can request both pages using the default URL Routing system, with the following urls.

http://localhost:your_port/Default.aspx 
http://localhost:your_port/Univercity/Students.aspx

Now let’s create our new routing system. Add a new folder named “App_Start” and create a new C# class “RouteConfig.cs”. This is just a convention we are making, taken from the default MVC structure. Start by adding a RegisterRoutes method. You have to add a using statement for the System.Web.Routing too.

using System.Web.Routing;

namespace AspNetUrlRouting.App_Start
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
        }
    }
}

For any custom virtual path you want to define, you must add a route to the “routes” RouteCollection object. Before adding some virtual paths, let’s first add a Global.asax (Global Application class item) file to our project, and make our new Routing system work.

using AspNetUrlRouting.App_Start;
using System.Web.Routing;

namespace AspNetUrlRouting
{
    public class Global : System.Web.HttpApplication
    {

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

Now let’s create our first Fixed routes into the RegisterRoutes function. Assume that we want the Default.aspx page to be indeed the default, which means that if you request http://localhost:your_port/ you want the Default.aspx page to be displayed. At this time, if you do this you will get the following error.
web-forms-urlrouting_02
Make the following addition inside the RegisterRoutes function. Build your project and request the previous URL again.

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("default", "", "~/Default.aspx");
        }

web-forms-urlrouting_03
You use the RouteCollection.MapPageRoute to define a new route. It takes three parameters, the route name, the routeURL and the physical file you want to map to.
web-forms-urlrouting_04
Add two fixed URLs that rich the /univercity/Students.aspx page.

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("default", "", "~/Default.aspx");
            routes.MapPageRoute("students1", "students", "~/Univercity/Students.aspx");
            routes.MapPageRoute("students2", "univercity/students", "~/Univercity/Students.aspx");
        }

Now the following two URLs will map the Students.aspx page.

http://localhost:your_port/students
http://localhost:your_port/Univercity/Students

web-forms-urlrouting_05
Let’s be honest here, this type of URLs are much more elegant and user friendly than the default “full-path” URLs. Assuming that you wanted all URLs in the form of “{something}/default” match the Default.aspx page, you may think that you have to add dozens of routes in your RegisterRoutes method. This is where variable segments comes into the scene. Adding the following route will make this possible.

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("default", "", "~/Default.aspx");
            routes.MapPageRoute("students1", "students", "~/Univercity/Students.aspx");
            routes.MapPageRoute("students2", "univercity/students", "~/Univercity/Students.aspx");
            routes.MapPageRoute("default_all", "{anything}/default", "~/Default.aspx");
        }

web-forms-urlrouting_06
We said previously that the RegisterRoutes method takes three parameters, but that was the simplest method overloading. In fact, there are 5 overloads for this method that supports other URL Routing features. If you are an MVC developer, you will know that you can add constraints to your mapped routes. Let’s modify the last route we added so that the {anything} segment won’t actually match anything but a batch of specified words.

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("default", "", "~/Default.aspx");
            routes.MapPageRoute("students1", "students", "~/Univercity/Students.aspx");
            routes.MapPageRoute("students2", "univercity/students", "~/Univercity/Students.aspx");
            //routes.MapPageRoute("default_all", "{anything}/default", "~/Default.aspx");
            routes.MapPageRoute("default_all", "{anything}/default", "~/Default.aspx",
                false, null,
                new RouteValueDictionary { { "anything", "univercity|school|classes" } });
        }

You define constraints by creating a RouteValueDictionary object for a specific segment variable. Here we declared that the {anything} segment can only match 3 specific words, which means that the previous URL will now crash.
web-forms-urlrouting_07
web-forms-urlrouting_08
Last thing I wanna show you, is how to retrieve route values in the code behind file. Add the following route that matches the Students.aspx page and pass an extra integer parameter.

public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapPageRoute("default", "", "~/Default.aspx");
            routes.MapPageRoute("students1", "students", "~/Univercity/Students.aspx");
            routes.MapPageRoute("students2", "univercity/students", "~/Univercity/Students.aspx");
            //routes.MapPageRoute("default_all", "{anything}/default", "~/Default.aspx");
            routes.MapPageRoute("default_all", "{anything}/default", "~/Default.aspx",
                false, null,
                new RouteValueDictionary { { "anything", "univercity|school|classes" } });
            routes.MapPageRoute("hack_student", "get/students/{id}", "~/Univercity/Students.aspx",
                false, null,
                new RouteValueDictionary { { "id", "[0-9]*" } });
        }

In the code behind file add the following code in the Page_Load event.

public partial class Students : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Route myRoute = RouteData.Route as Route;
            if (myRoute != null && myRoute.Url == "get/students/{id}")
            {
                string id = RouteData.Values["id"].ToString();
                Response.Write("Student: " + id + "<br/>" +
                    "Name: Chris");
            }
        }
    }

Here we get the matched route and if this isn’t null we read it’s routeUrl parameter. If this matches the last added route then we can read the {id} segment value through the “RouteData” object.
web-forms-urlrouting_09
This way you can create the so called Hackable URLs in your Web Forms projects. For example you could have a route like {semester}/students/{id}, read the values in the code behind file and send back the respective values. That’s it, we saw quite valuable concepts on URL Routing on this post that allows you to use user friendly URLs on your web application. You can download the project we built from here. I hope you enjoyed the post!

Advertisements


Categories: ASP.NET

Tags: , ,

3 replies

  1. Very helpful post. Glad to see people still sharing web forms content since there are those of us who will be supporting it for a while to come. 🙂 Again, thank you very much.

  2. Actually no matter if someone doesn’t understand then its up to other
    users that they will assist, so here it takes place.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Chara Plessa

The purpose of this blog is to broaden my education, promote experimentation and enhance my professional development. Albert Einstein once said that “If you can’t explain it simply, you don’t understand it well enough” and I strongly believe him!

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Kumikoro

A Front End Developer's Blog

Muhammad Hassan

Full Stack developer with expertise in ASP.NET | MVC | WebAPI | Advanced Javascript | AngularJS | Angular2 | C# | ES6 | SQL | TypeScript | HTML5 | NodeJS, NUCES-FAST CS grad, MS candidate @LUMS, EX-Adjunct Faculty @NUCES-FAST, seasonal blogger & open-source contributor. Seattle, WA

Software Engineering

Web development

IEvangelist

.NET, ASP.NET, C#, MVC, TypeScript, AngularJS

leastprivilege.com

Dominick Baier on Identity & Access Control

Happy DotNetting

In Love with Technology

Knoldus

Knols of experience to your advantage

knowshnet

Search - Read - Request - Share

Rahul's space

Learn, Share and Grow with me !

Dhananjay Kumar

Developer Evangelist @Infragistics | MVP @Microsoft |

Journey to SQL Authority with Pinal Dave

SQL, SQL Server, MySQL, Big Data and NoSQL

Conficient Blog

Random bits of tech from @conficient

Code! Code! Code!

SOLID & KISS

Code Wala

Designing and coding

Microsoft Mentalist

A way to start with Microsoft Technologies

Tony Sneed's Blog

A glimpse into the lives of Tony & Zuzana Sneed

Sriramjithendra Nidumolu

Personal Notes of Sriramjithendra

%d bloggers like this: