Sunday 8 April 2007

URL Mapping-Rewriting, ASP.NET C-Sharp

Problem
Hi folks. Recently, I did custom content management software for a website.
The client wanted
  • The content to be editable and to be served from database.
  • Search engine friendly URLs (e.g. They would like “/finance/loan.aspx” instead of “ShowContents.aspx?ID=23”).
  • Postback should still work on these virtual URLs.
  • References to the images, css files, themes should stay intact.
Solution
After about a day’s research, I came up with following simple solution.
You can download the code from my article URLMapping

STEP 1
  • Create “ShowContents.aspx", that serves content based on the ContentID passed in the QueryString.
  • To enable postbacks to the raw URL in the Page_Load() event of ShowContents.aspx, insert following line
    Context.RewritePath(Path.GetFileName(Request.RawUrl));
STEP 2
  • Capture the URL requested by the user in the Application_BeginRequest() event of Global.asax.
  • Find the ID of the content from database that is relevant to this URL
  • ReWritePath to ShowContents.aspx?ContentID=XX. The user will see requested URL in the address bar with the desired content.
  • Any files that physically exist on the server will still get served as usual.

Code

File: Global.asax (Create one if does not already exist)


<%@ Import Namespace="System.IO" %>

protected void Application_BeginRequest(object sender, EventArgs e)

{

// If the requested file exists

if (File.Exists(Request.PhysicalPath))

{

// Do nothing here, just serve the file

}

// If the file does not exist then

else if (!File.Exists(Request.PhysicalPath))

{

// Get the URL requested by the user

string sRequestedURL = Request.Path.Replace(".aspx", "");

// To get ID of the content from database

int nId = 0;

// You can retrieve the ID of the content from database that is relevant to this URL

////// nId = GetContentIDByPath(sRequestedURL); \\\\\

// The ShowContents.aspx page should show contents relevant to the ID that is passed here

string sTargetURL = "~/ShowContents.aspx?ContentID=" + nId.ToString();

// Owing to RewritePath, the user will see requested URL in the address bar

// The second argument should be false, to keep your references to images, css files

Context.RewritePath(sTargetURL, false);

// ###### I M P O R T A N T ######

// To enable postback in ShowContents.aspx page you should have following

// line in it's Page_Load() event. You will need to import System.IO.

// Context.RewritePath(Path.GetFileName(Request.RawUrl), false);

}

}


4 comments:

Paulo Moreno said...

Hello, great post ...

I do not know if possible, use this technique for virtual domains like as http://virtual.domain.com

Can you help me ?

Anonymous said...

thanks! this really helped me a lot!!

Anonymous said...

Good post.

Anonymous said...

Hi Manu

Great post that of yours!!!

I got a question: all working fine but I have a problem with MasterPages an css... I can`t read my css file, don't know why...

Copying all

ASPX FILE

<%@ Import Namespace="System"%>
<%@ Import Namespace="System.IO"%>
<%@ Import Namespace="System.data"%>
<%@ Import Namespace="System.data.sql"%>
<%@ Import Namespace="System.data.sqlclient"%>
<%@ Import Namespace="System.Web.UI.Page" %>
<%@ Import Namespace="System.Web.UI.htmlcontrols" %>

<script runat="server">

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Context.RewritePath(Path.GetFileName(Request.RawUrl))

Dim conexion As New SqlConnection()
conexion.ConnectionString = ConfigurationManager.ConnectionStrings("FichasConnectionString").ToString

Dim micomando As SqlCommand = conexion.CreateCommand()
micomando.CommandText = "SELECT Categoria, Title, Description, Header, Dims, TitCategoria from categorias WHERE IDCategoria=" & Request.QueryString("id")
conexion.Open()

Dim misdatos As SqlDataReader = micomando.ExecuteReader()
'Dim VAR As String
If misdatos.Read Then
Label1.Text = IIf(IsDBNull(misdatos(1)), "", misdatos(1).ToString.Trim)

End If
End Sub


GLOBAL ASX
<%@ Application Language="VB" %>
<%@ Import Namespace="System.IO" %>


<script runat="server">


Protected Sub Application_BeginRequest(ByVal sender As Object, ByVal e As System.EventArgs)
If File.Exists(Request.PhysicalPath) Then

End If

If Not File.Exists(Request.PhysicalPath) Then
Dim URLPEDIDA As String = Request.Path.Replace(".aspx", "")
Dim ID As String = URLPEDIDA.Substring(Request.Path.LastIndexOf("-") + 1)

If ID > 0 Then
Dim URLMOSTRADA As String = "~/CursoMaster.aspx?Id=" & ID
Context.RewritePath( URLMOSTRADA, True) --> false doesn't work either...
End If

End If

End Sub
</script>



COULD YOU HELP ME PLEASE?!?!?


JAVIER