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.