Tradepoint Business Management Solutions - Everything Business, connected.
Shopping CartCart: 0 Items, Total: $0.00
Login to your Account
Get a FREE Demo - Try Tradepoint for 30 days

How to change the default URL rewriting (SEO Friendly URLs) and use them in your site

Jun/14/2010

Related Products


With V4 of the Tradepoint ecommerce engine, the custom page routing engine has been removed in favour of ASP.NET V4 Routing. This allows for a 200% speed increase and for easier customization of the routes in your site so that you can customize how products, categories or any other page will be displayed on your site.

As a reminder you can download the base ecommerce site from: http://www.tradepoint360.com/ecommerce/demo.tradepoint360.com.zip

All custom routes are stored in the global.asax file in the root of your site. You will see the following default entries in the application_start event:

void Application_Start(object sender, EventArgs e)

{

//Note: Physical pages that exist will be ignored by default and displayed as normal.

System.Web.Routing.RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");

System.Web.Routing.RouteTable.Routes.Ignore("{resource}.svc/{*pathInfo}");

System.Web.Routing.RouteTable.Routes.Ignore("devexpress/{*pathInfo}");

System.Web.Routing.RouteTable.Routes.Ignore("{resource}.js");

System.Web.Routing.RouteTable.Routes.Ignore("styles/{*pathInfo}");

System.Web.Routing.RouteTable.Routes.Ignore("templates/{*pathInfo}");

System.Web.Routing.RouteTable.Routes.Ignore("app_themes/{*pathInfo}");

//These are order specific from most specific to least.

//Image rewrites

System.Web.Routing.RouteTable.Routes.Add("ProductDefaultImage", new System.Web.Routing.Route("images/products/{Model}/default.png", new Tradepoint.Enterprise.Web.Rewritting.TradepointImageRouteHandler(true, false)));

System.Web.Routing.RouteTable.Routes.Add("ProductThumbnailImage", new System.Web.Routing.Route("images/products/{Model}/thumbnail.png", new Tradepoint.Enterprise.Web.Rewritting.TradepointImageRouteHandler(true, true)));

System.Web.Routing.RouteTable.Routes.Add("ProductPhoto", new System.Web.Routing.Route("images/products/{Model}/photos/{Caption}.png", new Tradepoint.Enterprise.Web.Rewritting.TradepointImageRouteHandler(false, false)));

System.Web.Routing.RouteTable.Routes.Add("ProductPhotoThumbnail", new System.Web.Routing.Route("images/products/{Model}/thumbnails/{Caption}.png", new Tradepoint.Enterprise.Web.Rewritting.TradepointImageRouteHandler(false, true)));

//Other

System.Web.Routing.RouteTable.Routes.Add("ProductTypeModel", new System.Web.Routing.Route("products/{Model}/{Type}", new System.Web.Routing.PageRouteHandler("~/products/productpages/default.aspx")));

System.Web.Routing.RouteTable.Routes.Add("ProductModel", new System.Web.Routing.Route("products/{Model}", new System.Web.Routing.PageRouteHandler("~/products/productpages/default.aspx")));

System.Web.Routing.RouteTable.Routes.Add("PrimaryCategoryID", new System.Web.Routing.Route("categories/ID={ID}", new System.Web.Routing.PageRouteHandler("~/products/category.aspx")));

System.Web.Routing.RouteTable.Routes.Add("PrimaryCategoryName", new System.Web.Routing.Route("categories/{Name}", new System.Web.Routing.PageRouteHandler("~/products/category.aspx")));

System.Web.Routing.RouteTable.Routes.Add("GroupID", new System.Web.Routing.Route("groups/ID={ID}", new System.Web.Routing.PageRouteHandler("~/products/group.aspx")));

System.Web.Routing.RouteTable.Routes.Add("DepartmentID", new System.Web.Routing.Route("departments/ID={ID}", new System.Web.Routing.PageRouteHandler("~/products/department.aspx")));

System.Web.Routing.RouteTable.Routes.Add("GroupName", new System.Web.Routing.Route("groups/{Name}", new System.Web.Routing.PageRouteHandler("~/products/group.aspx")));

System.Web.Routing.RouteTable.Routes.Add("DepartmentName", new System.Web.Routing.Route("departments/{Name}", new System.Web.Routing.PageRouteHandler("~/products/department.aspx")));

//Add generic handler for all arbitrary urls if all else doesn't line up.

System.Web.Routing.RouteTable.Routes.Add("Generic", new System.Web.Routing.Route("{*URL}", new Tradepoint.Enterprise.Web.Rewritting.TradepointRouteHandler()));

}

 

You'll note that there is a section for exceptions. These are URLs that you don't want it to map. It will ignore any mappings that might have been followed.

The rest go from most specific to least, finally getting to "all" which then processes any custom URLs that have no matching pattern that you might have for products or categories etc.

Note that the first part of the System.Web.Routing.RouteTable.Routes.Add method is the name of the rewritting rule. This is important, because you will use this to construct your URL. The following example shows how to construct a URL based on a product image:

The Route: 

System.Web.Routing.RouteTable.Routes.Add("ProductDefaultImage", new System.Web.Routing.Route("images/products/{Model}/default.png", new Tradepoint.Enterprise.Web.Rewritting.TradepointImageRouteHandler(true, false)));

We have a route named ProductDefaultImage that we're going to reference. The route is "images/products/{Model}/default.png". "{Model}" references a variable. That is it could be anything in that spot in the URL. In this case, {Model} is the Product Model. Thus as an example the following URL would match this route: /images/products/ACM-121/default.png".  The system will then find ACM-121 as the model and look it up in the database automatically and display the default image for that model. (note that there is a separate route for the thumbnail version.)

While you could just concatenate a path in your code that references this URL, the better approach is to reference the name of the route and have the system go and build it for you. That way, if you ever change the route, the system will automatically change all of the URLs that reference the named route.

To reference the route and have it build it for you we'll use code like this:

<img src="<%#GetRouteUrl("ProductDefaultImage", new { Model = Eval("Model") }) %>"/>

What this does is set the src of the image control to the RouteURL. GetRouteURL is a standard ASP.net function that takes the name of the route as the first parameter and the second parmeter is a variant named list of the variables in the route. In this case our {Model} variable is set to the Evaluated value from the databinding, but it could just as easily be taken from the product object or any other variable you desire. You can have routes with multiple variables and simply add a comma after the first variable and add the second one in the same manner.

The added benefit of this approach is that the parmeters are NOT passed as request.QueryString items. They are stored in the Page.RouteData.Values collection. You'll see in the /products/category.aspx.cs how we use these to get the correct variables and lookup the category in question:

DataContext.CategorySet.MergeOption = System.Data.Objects.MergeOption.NoTracking;

System.Linq.IQueryable<Category> CategoryList = null;

if (RouteData.Values.ContainsKey("ID")) {

Guid ID = new Guid(RouteData.Values["ID"].ToString());

CategoryList = from c in DataContext.CategorySet where c.ID == ID select c;

} else if (RouteData.Values.ContainsKey("Name")) {

string Name = RouteData.Values["Name"].ToString().Replace("+", " ").Replace("_", " ");

CategoryList = from c in DataContext.CategorySet where c.Name == Name select c;

} else if (Request.QueryString["ID"] != null) {

Guid ID = new Guid(Request.QueryString["ID"].ToString());

CategoryList = from c in DataContext.CategorySet where c.ID == ID select c;

}

category = CategoryList.Where(c => c.CategoryType == 12).FirstOrDefault();

if (category == null) {

Response.Redirect("/securityerror.aspx");

return;

}

Note how we always test to see if the object equals null and redirect to our security error page. By doing so we eliminate a possible ASP.NET error showing up to the end user and we protect the site from hacking. This combined with Linq to Entities prevents sql injection from occuring. (The final if statement is used for backwards compatibility only.)

By using the routing system built into V4 of the Tradepoint Ecommerce system you can create any rules that you wish to create fully SEO friendly URLs. There are a couple of "gotchas" that you'll want to note:

  1. Always apply your rules from most specific to least or your route will never be processed.
  2. Always test your pages to make sure that other routes are unintentionally matching a route that you've created. You may have to change it as a result of your testing.
  3. Always use the GetRouteURL function whenever possible. The only two times we do not use these are for Product and Category URLs. The reason for this is because they have generic URL support so ANYTHING could match so we create specific ones.
  4. Please see here: http://weblogs.asp.net/scottgu/archive/2009/10/13/url-routing-with-asp-net-4-web-forms-vs-2010-and-net-4-0-series.aspx for a good getting started guide to URL rewritting in .NET.
  5. Always use dashes (-) to replace spaces both when encoding and when decoding your URLs otherwise some browsers may not work and your SEO optimizations may be compromised.


Thank you for Adding an Item to your cart

# of Items Added: 1
Total of Items Added: 0.00
Continue Shopping Show Your Shopping Cart