ASP.NET Web Pages - Routing

Routing enables you to use a specific path for your website. For example if you had a products website, the URL structure might be like this:

www.example.com/products/electronics/monitiors

A URL like the one above is much easier to understand than a URL like www.example.com/products.aspx?id=250. It is also helpful for SEO, as some search engines and robots do not read parameters.  The URL does not need to be linked to a specific file or directory, as products/electronics might not even exist.

For example, the following URL uses routing:

http://blog.thecodingguys.net/article/36/2013/august/asp-net-webpages-multiple-submit-buttons

This is a clearly understandable URL, both by humans and search engines. If it looked like

http://blog.thecodingguys.net/article.aspx?id=240, then it would be hard to understand. The blog URL is also quite different, as the article does not even exist, and it follows a pattern:

  1. Article ID
  2. Article Year
  3. Article Month
  4. Article Name

It is also a ‘hack-able’ and user friendly URL if you went and chopped off, preview from the end of the article name, you would be redirected.

Create a new website based on the bakery template and name the website  Routing. Create an AppStart file and then create an App_Code folder. Next, click nugget and type “RouteHandler” and add the RouteHandler for Web Pages. A file will be installed in App_code called WebPageRouteHandler.cs.

In the _AppStart file add the following line:

@using System.Web.Routing;

@{
}

Syntax

@{
RouteTable.Routes.MapWebPageRoute(string routeurl, string virtual path, object default values)
}

The MapWebPageRoute takes 5 arguments, the first 2 are compulsory and the last 3 are optional. The first one requires the URL pattern, for example: /products/electronics/1/Samsung-tv. The second parameter is the file which is going to serve this route. The rest are all optional.

3rd argument – sets the default values

4th argument – sets object constraints

5Th Argument – sets routename

For our route add the following line:

@{
RouteTable.Routes.MapWebPageRoute("products/{category}/{id}/{name}", "~/products.cshtml",  new {category = "food", id = "1", name="default" });
}

The route values that are in curly brackets are values which will be requested from the database. You can also specify optional parameters: you simply set the default value to -1, but optional parameters must go at the end. In the database Products Table, add a column called Category and then copy this:

:ASP.NET Routing Products Table

The last three are the new values we have added. The images must be put in Images/thumbnails folder. In the default.cshtml file change the HTML starting from the <div id=”productwrapper”>

HTML Code:

<div id="productsWrapper">
    <ul id="products" data-role="listview" data-inset="true">
        @foreach (var p in products) {
            <li class="product">
                <a href="~/products/@p.Category/@p.id/@p.Name" title="Order @p.Name">
                    <img class="hide-from-desktop" src="~/Images/Products/Thumbnails/@p.ImageName" alt="Image of @p.Name" />             
                    <div class="productInfo">
                        <h3>@p.Name</h3>
                        <img class="product-image hide-from-mobile" src="~/Images/Products/Thumbnails/@p.ImageName" alt="Image of @p.Name" />
                        <p class="description">@p.Description</p>
                        <p class="price hide-from-desktop">@string.Format("{0:C}", p.Price)</p>                   
                    </div>
                </a>
                <!-- Desktop only -->
                <div class="action  hide-from-mobile">
                    <p class="price">@string.Format("{0:C}", p.Price)</p>
                    <a class="order-button" href="~/order/@p.Id" title="Order @p.Name">Order Now</a>
                </div>
            </li>
        }
    </ul>
</div>

Here we changed the links so they are linked to the products page. Now let’s create the products page: in the root directory create a page called Products and copy this code:

C# Code

@{

var pCategory = Context.GetRouteValue("Category");
var pId = Context.GetRouteValue("id");
var pName = Context.GetRouteValue("name");


if (pCategory == null || pId == null || pName == null)
{
    Response.Redirect("~/");
}

var db = Database.Open("bakery");
var products = db.QuerySingle("SELECT * FROM PRODUCTS Where Category=@0 AND Id=@1 AND Name=@2", pCategory, pId, pName);


var id = products.Id;
var Name = products.Name;
var Description = products.Description;
var Price = products.Price;
var Image = products.ImageName;

}

First we have 3 variables at the top which request the route values, and we need to make sure they are not null. If they are null we need to redirect or we can specify a default value. For the database query we select the category, Product ID and Product Name.

HTML Code

<div id="productsWrapper">
    <ul id="products" data-role="listview" data-inset="true">
            <li class="product">
                <a href="~/order/@id" title="Order @Name">
                    <img class="hide-from-desktop" src="~/Images/Products/Thumbnails/@Image" alt="Image of @Image" />
                    <div class="productInfo">
                        <h3>@Name</h3>
                        <img class="product-image hide-from-mobile" src="~/Images/Products/Thumbnails/@Image" alt="Image of @Name" />
                        <p class="description">@Description</p>
                        <p class="price hide-from-desktop">@string.Format("{0:C}", Price)</p>                   
                    </div>
                </a>
                <!-- Desktop only -->
                <div class="action  hide-from-mobile">
                    <p class="price">@string.Format("{0:C}", Price)</p>
                    <a class="order-button" href="~/order/@id" title="Order @Name">Order Now</a>
                </div>
            </li>
    </ul>
</div>

Run the website; when you click on a product it will take you to the products page. The URL will look like this: /products/Electronics/9/Samsung%20TV.

Making URLs Hackable

We can make URLs more user-friendly; by 'hackable' we mean parts of the URL can be chopped off and it should perform some redirect. The directory products/electronics does not exist if someone removed electronics/9/Samsung. In this case you would get a 500 internal server error. We can solve this by simply creating a products folder and sub-folders for each category. Create a folder named Products, then another folder called Electronics.

Then in the root of the Products folder create a page start file and copy:

@
{
Response.Redirect("~/");
}

For this example we simply did a redirect; however you could always provide users with the latest products.

Summary

  • Routing allows you to use a specific path for your website
  • Routing is good for SEO
  • Routing takes two compulsory arguments: the URL pattern and physical file