Introduction
URL rewriting is the process of intercepting an incoming Web request and redirecting the request to a different resource. When performing URL rewriting, typically
the URL being requested is checked and, based on its value, the request is redirected to a different URL. For example, a website restructuring web pages of a specified directory
or article and when accessing a web page from an article or directory by URL then the URL is automatically moved on to the Blog directory. That happens by URL rewriting.
This article introduces URL rewriting using a data-driven application. This application creates various blogs and these blogs are accessed by the title of the blog.
Database Design for Application
First of all we create a table Blog that has blog information like title, content and so on. This table has a primary key id and a Visit field for the total number
visits for a specific blog.
CREATE TABLE Blog
(
Id int Identity(1,1) Primary Key,
Title nvarchar(100),
Content nvarchar(max),
Visit int default 0,
createDate datetime default getDate()
)
After designing the table we create two Stored Procedures, one for inserting
a blog and another for counting the blog visitors. First we create the proc_BlogInsert
Stored Procedure to insert a new record or blog entry in the blog table.
CREATE PROCEDURE proc_BlogInsert
@title nvarchar(100),
@content nvarchar(max)
AS
BEGIN
if not exists(SELECT Id from Blog Where Title = @title)
begin
INSERT INTO Blog (Title,Content) VALUES (@title,@content)
end
END
Now we create another Stored Procedure, "proc_VisitorIncrement", to increment the visitor counter when a blog is visited.
CREATE procedure proc_VisitorIncrement
(
@id int
)
AS
begin
update Blog set Visit += 1 where Id = @id
end
Create Business object and Data Access Layer
We create a Blog class that has properties and a constructor for a blog and it will be used to pass blog data on the UI.
namespace URLRewrittingExample.Blogs
{
public class Blog
{
private int mId=0;
private string mTitle = string.Empty;
private string mContent = string.Empty;
private int mVisit = 0;
public Blog(string title, string content)
{
mTitle = title;
mContent = content;
}
public Blog(int id, string title, int visit)
{
mId = id;
mTitle = title;
mVisit = visit;
}
public Blog(int id, string title, int visit, string content)
{
mId = id;
mTitle = title;
mVisit = visit;
mContent = content;
}
public int Id
{
get { return mId; }
set { mId = value; }
}
public string Title
{
get { return mTitle; }
}
public string Content
{
get { return mContent; }
}
public int Visit
{
get { return mVisit; }
set { mVisit = value; }
}
}
}
We need a connection with the database to perform create, insert, update and delete operations on the blog table so we define a connection string in the
web.config file.
<connectionStrings>
<add name="DbConnectionString"
connectionString="Data Source=sandeepss-PC;Initial Catalog=CodeFirst;User ID=sa; Password=123456"
providerName="System.Data.SqlClient" />
</connectionStrings>
After that we create a data access layer. In this layer we have a class BlogDAL
(BlogDAL.cs) that has all database related operations for a blog in the application.
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;
namespace URLRewrittingExample.Blogs
{
public class BlogDAL
{
public static SqlConnection DatabaseConnection()
{
string connectionString =
ConfigurationManager.ConnectionStrings["DbConnectionString"].ConnectionString;
SqlConnection con = new SqlConnection(connectionString);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
return con;
}
public int BlogInsert(Blog objBlog)
{
using (SqlCommand cmd = new SqlCommand("proc_BlogInsert", DatabaseConnection()))
{
using (SqlDataAdapter dap = new SqlDataAdapter(cmd))
{
dap.InsertCommand = cmd;
dap.InsertCommand.CommandType = CommandType.StoredProcedure;
dap.InsertCommand.Parameters.AddWithValue("@title", objBlog.Title);
dap.InsertCommand.Parameters.AddWithValue("@content", objBlog.Content);
return dap.InsertCommand.ExecuteNonQuery();
}
}
}
public List<Blog> GetAllBlogs()
{
List<Blog> blogsList = new List<Blog>();
SqlCommand cmd = new SqlCommand("Select Id,Title,Visit from Blog", DatabaseConnection());
IDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
blogsList.Add(new Blog(Convert.ToInt32(dr["Id"].ToString()),dr["Title"].ToString(),
Convert.ToInt32(dr["Visit"].ToString())));
}
dr.Close();
return blogsList;
}
public Blog GetBlogById(int id)
{
Blog objBlog = null;
SqlCommand cmd = new SqlCommand("Select Title,Visit,Content from Blog where Id="+id, DatabaseConnection());
IDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
objBlog = new Blog(id,
dr["Title"].ToString(),
Convert.ToInt32(dr["Visit"].ToString()),
dr["Content"].ToString());
}
dr.Close();
return objBlog;
}
public int BlogVisitorIncrement(int id)
{
using (SqlCommand cmd = new SqlCommand("proc_VisitorIncrement", DatabaseConnection()))
{
cmd.CommandType = CommandType.StoredProcedure;
using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
{
adapter.UpdateCommand = cmd;
SqlParameter param = new SqlParameter("@id",id);
adapter.UpdateCommand.Parameters.Add(param);
return adapter.UpdateCommand.ExecuteNonQuery();
}
}
}
}
}
Our business object and data access layer is ready.
Application UI Design
We create a UI design for the application. This application has a three-part UI.
- Insert a Blog
- Show All Blog List
- Show individual Blog with Content
Let's see each one by one.
Insert a Blog
To insert a blog we design a UI page that can take two inputs, one is the blog title and the other is blog content. For the blog title we use a TextBox and
for the blog content we use an Editor of AjaxControlToolkit. We also use a submit button on the page that inserts a blog record.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="AnExampleOfURLRewriting.Index" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit.HTMLEditor" TagPrefix="cc1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="Style/BaseStyleSheet.css" rel="stylesheet" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div class="formRowContainer">
<div class="labelContainer">Title</div>
<div class="valueContainer">
<asp:TextBox ID="txtTitle" runat="server"></asp:TextBox>
</div>
</div>
<div class="clearStyle"></div>
<div class="formRowContainer">
<div class="labelContainer">Content</div>
<div class="valueContainer">
<cc1:Editor id="blogEditor" runat="server"></cc1:Editor>
</div>
</div>
<div class="clearStyle"></div>
<div class="buttonContainer">
<asp:Button ID="btnSubmit" runat="server" Text="Create" OnClick="btnSubmit_Click" />
</div>
</form>
</body>
</html>
After designing the UI, we write the logic on its code behind file for inserting a blog. There is a submit button click event that insert a record in the database.
using System;
using URLRewrittingExample.Blogs;
namespace AnExampleOfURLRewriting
{
public partial class Index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Blog objBlog = new Blog(txtTitle.Text.Trim(), blogEditor.Content);
BlogDAL objBlogDAL = new BlogDAL();
int effectedRows = objBlogDAL.BlogInsert(objBlog);
}
}
}
Figure 1.1 : UI screen for new blog insert
Show All Blog List
We create a UI screen that shows all blog titles along with total visitor counter. To create a blog list we use a repeater control of ASP.Net. In a repeater we
use a link button for the title so we can click on the title and get blog data on the new page.
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="BlogList.aspx.cs"
Inherits="URLRewrittingExample.Blogs.BlogList" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="../Style/BaseStyleSheet.css" rel="stylesheet" />
</head>
<body>
<form id="form2" runat="server">
<div>
<asp:Repeater ID="rptBlog" runat="server" OnItemDataBound="rptBlog_ItemDataBound">
<HeaderTemplate>
<table class="gridtable">
<tr>
<th>Title</th>
<th>Visit</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:LinkButton id="lnkTitle" runat="server"
Text='<%#Eval("Title") %>'></asp:LinkButton></td>
<td><%#Eval("Visit") %></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
Now create a method in the code behind file for a repeater bind and create a custom URL according to the title of the blog.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace URLRewrittingExample.Blogs
{
public partial class BlogList : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ShowBlogList();
}
}
private void ShowBlogList()
{
BlogDAL objBlogDAL = new BlogDAL();
rptBlog.DataSource = objBlogDAL.GetAllBlogs();
rptBlog.DataBind();
}
protected void rptBlog_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
LinkButton lnkTitle = (LinkButton) e.Item.FindControl("lnkTitle");
lnkTitle.Style.Add("text-decoration", "none");
Blog Item =(Blog) e.Item.DataItem;
lnkTitle.PostBackUrl = GenerateURL(Item.Title, Item.Id);
}
}
public static string GenerateURL(string title, int Id)
{
string strTitle = title.Trim();
strTitle = strTitle.ToLower();
strTitle = strTitle.Replace("c#", "C-Sharp");
strTitle = strTitle.Replace(" ", "-");
strTitle = strTitle.Trim();
strTitle = strTitle.Trim('-');
strTitle = "~/Blogs/"+strTitle+"-"+Id.ToString() + ".aspx";
return strTitle;
}
}
}
Figure 1.2 : Show all blog list
Show individual Blog with Content
Now create a simple page with a div to show blog content along with blog title and visitor number.
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="BlogShow.aspx.cs" Inherits="URLRewrittingExample.Blogs.BlogShow" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form3" runat="server">
<div>
<div id="divTitle" runat="server"></div>
<span id="spVisitor" runat="server"></span>
<div id="divContent" runat="server"></div>
</div>
</form>
</body>
</html>
After that we write logic for the code behind page for two operations, one is the show content page and the other is for the visitor counter. The visitor counter
increments when the page is initialized.
using System;
namespace URLRewrittingExample.Blogs
{
public partial class BlogShow : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
if (Request.QueryString.Get("id") != null)
{
int id= Convert.ToInt32(Request.QueryString.Get("id"));
BlogDAL objBlogDAL = new BlogDAL();
objBlogDAL.BlogVisitorIncrement(id);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (Request.QueryString.Get("id") != null)
{
int id = Convert.ToInt32(Request.QueryString.Get("id"));
DisplayBlog(id);
}
}
private void DisplayBlog(int id)
{
BlogDAL objBlogDAL = new BlogDAL();
Blog objBlog = objBlogDAL.GetBlogById(id);
divTitle.InnerHtml = objBlog.Title;
spVisitor.InnerHtml ="Total Visits "+ objBlog.Visit;
divContent.InnerHtml = objBlog.Content;
}
}
}
Figure 1.3 Blog content with different URL
In Figure 1.3 you have noticed a different SEO friendly URL for a .aspx page. That page doesn't exist in our blog application but it is created by URL rewriting.
URL rewriting implements the global.asax file's Application_BeginRequest
event. This event calls every request and maps the URL on based on the requested URL.
protected void Application_BeginRequest(object sender, EventArgs e)
{
string origionalpath = Request.Url.ToString();
string subPath = string.Empty;
string blogId = string.Empty;
int id = 0;
if (origionalpath.Contains("Blogs"))
{
if (origionalpath.Length >= 22)
{
subPath = origionalpath.Substring(22);
if (subPath.Length >= 1)
{
blogId = Regex.Match(subPath, @"\d+").Value;
bool isValid = Int32.TryParse(blogId, out id);
if (isValid)
{
Context.RewritePath("BlogShow.aspx?id=" + id);
}
}
}
}
}
Note: Download the zip folder that has all files for this application and learn URL rewriting with ASP.NET using 3-tier architecture.