Search engines like human-readable URLs with keywords in it, and hesitate to respect messy URLs with a lot of query-string parameters. So, to make our ASP.NET database-driven website SEO-friendly we have to get rid of our complex URLs.
Example of a "SEO-friendly" URL:
http://www.jitbit.com/mailjet-newsletter-software.aspx
Example of a "SEO-unfriendly" URL:
http://www.jitbit.com/product.aspx?ProductID=18
Solution 1: Fake pages and "Server.Transfer". As you can see the two URLs above point to the same page. Basically it is the same page and it works like this: the page mailjet-newsletter-software.aspx contains no code at all and performs a Server.Transfer (aka server-side redirect) to product.aspx like this:Server.Transfer("product.aspx?ProductID=18");
That's it. We have one "product.aspx" page which expects a "ProductID" parameter and a lot of "fake pages" with SEO-friendly names like firstproduct.aspx, secondproduct.aspx etc., which simply perform a Server.Transfer to the "product.aspx" with the right ProductID.
Simple, isn't it?
But this solution requires a lot of hard-coding - we will have to create all these fake pages and add a Server.Transfer command. So let's go a little further: we will create one base class for all our "fake pages" and add a record to the "tblProducts" table in the database:
| tblProducts | ||
| ProductID | ProductName | ProductPage |
|---|---|---|
| 1 | First Product | firstproduct.aspx |
| 2 | Second Product | secondproduct.aspx |
| 3 | Third Product | thirdproduct.aspx |
public class ProductPage : PageNow we have to create our fake pages, inherit them all from the ProductPage class and voi la - that's it! We can also optionally remove all the HTML-code from the aspx-files, leaving the "Page" directive only.
{
private SqlConnection cn;
private SqlCommand cmd;
protected override void OnLoad(EventArgs e)
{
//lets initialize our database connection
//remember to specify the connection string
cn = new SqlConnection(yourConnectionString);
cmd = new SqlCommand();
cmd.Connection = cn;
//determine the page being requested in the browser
string pageFileName = Request.Path.Substring(Request.Path.LastIndexOf("/")+1);
//get the right ProductID from the database
cmd.CommandText = "SELECT ProductID FROM tblProducts WHERE ProductPage=@ProductPage";
cmd.Parameters.AddWithValue("@ProductPage", pageFileName);
cn.Open();
object productID = cmd.ExecuteScalar();
cn.Close();
//if ProductID found
if(productID!=null && productID!=DBNull.Value)
{
//let's transfer the execution
Server.Transfer("product.aspx?ProductID=" + productID.ToString());
}
}
}
Solution 2: Virtual Pages. This method is pretty similar, except that we don't need to create any pages at all. Instead, we will add an HttpModule, which intercepts HTTP requests, and the user requests a non-existent page, performs a Rewrite operation. First we will create our HttpModule:
namespace URLRewriteNow we have to register our HttpModule in the web.config:
{
public class ProductPageModule : IHttpModule
{
public ProductPageModule()
{
}
public void Dispose()
{
}
public void Init(HttpApplication application)
{
//let's register our event handler
application.PostResolveRequestCache += (new EventHandler(this.Application_OnAfterProcess));
}
private void Application_OnAfterProcess(object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
//the file being requested is not found
if (!File.Exists(application.Request.PhysicalPath))
{
//replace the "newURL"
//with your own value
string newURL = "product.aspx?ProductID=18";
context.RewritePath(newURL);
}
}
}
}
<httpModules>
<add type="URLRewrite.ProductPageModule, URLRewrite" name="ProductPageModule" />
<httpModules>
That's it.
8 comments:
This is quite a helpful post, but I was wondering if you could go into a little more detail as to what each line of code is doing so we can all have a better understanding of it.
Thanks for leaving your comment Chad! I have added comments to the code and made it a bit more "readable".
Thanks a lot! It makes more sense now. I am a VB programmer so I don't really know C# as well. The comments help!
Will you be implementing this with aspNetForum software? I was looking at purchasing a license, and was considering editing the source to make forum URLS seo friendly.
I am sorry for the delay in responding. Unfortunately the current version does not support SEO-friendly URLs, but we plan to add it in the future.
How should the link calling the product page be ? I have something like
Toys
But I get application.Request.PathInfo as empty. Am I missing something ?
Thank you
Very useful post... But I am getting an error in the class file ddl I am creating...
Error 1 'URLRewrite.ProductPageModule' does not implement interface member 'System.Web.IHttpModule.Dispose()' C:\Documents and Settings\sacred\Local Settings\Application Data\Temporary Projects\URLRewrite\Class1.cs 8 18 URLRewrite
any ideas?
I started doing this
application.Disposed += (new EventHandler(this.Application_Disposed))
but when I do the cuntion
private void Application_Disposed(Object source, EventArgs e)
{
}
what exactly am I disposing? Confused... in the old days we had a constructor and a destructor... .net I have gotten my head around the way it is suppose to work. As I thought it did the automatic cleanup so no constructing and destructing.
Yet this message indicates otherwise...
simply add this to your module code:
public void Dispose()
{
}
(I will update the article)
Post a Comment