We're Hiring!
Take the next step in your career and work on diverse technology projects with cross-functional teams.
LEARN MORE
Mountain West Farm Bureau Insurance
office workers empowered by business technology solutions
BLOG
3
14
2011

SEO Friendly Routes with ASP.net MVC 3

Last updated:
7.23.2021

One of the most important things for a modern-day website is for it to be easily found. If nobody can find your website, then it isn't very useful. One thing you can do to help is by creating URLs that contain useful information. Having a high search engine ranking is very important for businesses to have. If you are an online shopping business, you want to try and reach high in the search engine rankings to gain better visibility for the sale of your products, shopify seo can help your business with this. Google will usually rank a site higher with a URL like http://www.northwind.com/products/3/aniseed-syrup compared to http://www.northwind.com/products/3. In addition to being ranked higher by search engines, it is a lot easier for humans to remember as well. This is particularly true in newer markets, such as the e-cigarette industry for instance. To learn more about how SEO can be useful for vaping businesses, check out this guide to Vape Store SEO. Today, I am going to show you an easy way to create these SEO-style routes for your ASP.net MVC 3 applications.

The first thing we need to do in order to get this to work is create a route that will match this pattern:

public static void RegisterRoutes(RouteCollection routes)
{
   routes.MapRoute(
       "ProductDetails",
       "products/{productId}/{productName}", // URL
       new { controller = "Products", action = "Details", productName = UrlParameter.Optional
}, // URL Defaults
       new { id = @"\d+" } // URL Constraints
   );
}


What this does is register a route in our application that matches the pattern /products/id/ and optionally /products/id/name. The product name is optional but the id is required and must be an integer.

Now that we have our route in place we need to create the controller that will handle requests that match the route:

public class ProductsController : Controller
{
   public ActionResult Index(int id, string productName)
   {
       // retrieve the product from the database
       Product product = db.Products.Single(p => p.ProductID == id);

       return View(product);
   }
}


This controller action will take in an id and a product name, retrieve a product based on the id and then return the view, passing in the Product data. You might have noticed that the controller isn't using the productName at the moment. Currently, if we have a product that contains spaces, the URL will encode the string like so:

http://www.northwind.com/products/3/aniseed%20syrup

This is far from ideal. Let's go ahead and fix that problem.

public static class StringHelpers
{
   public static string ToSeoUrl(this string url)
   {
       // make the url lowercase
       string encodedUrl = (url ?? "").ToLower();

       // replace & with and
       encodedUrl = Regex.Replace(encodedUrl, @"\&+", "and");

       // remove characters
       encodedUrl = encodedUrl.Replace("'", "");

       // remove invalid characters
       encodedUrl = Regex.Replace(encodedUrl, @"[^a-z0-9]", "-");

       // remove duplicates
       encodedUrl = Regex.Replace(encodedUrl, @"-+", "-");

       // trim leading & trailing characters
       encodedUrl = encodedUrl.Trim('-');

       return encodedUrl;
   }
}


The above code creates an extension method for the string type and returns an "SEO-encoded" URL using the following steps:

  1. Convert the string to lowercase.
  2. Replace the & symbol with the word and
  3. Remove unwanted characters by replacing with a space (currently only ')
  4. Replace all other characters other than letters/numbers with a -
  5. Remove duplicate -'s from the string (we don't want aniseed--syrup, etc.)
  6. Remove leading/trailing -'s from the string

Now, a string like "AnIseeD Syrup" will be converted to "aniseed-syrup". Now we can modify our controller to make use of this functionality.

public class ProductsController : Controller
{

   public ActionResult Index(int id, string productName)
   {
       // retrieve the product from the database
       Product product = db.Products.Single(p => p.ProductID == id);

       // make sure the productName for the route matches the encoded product name
       string expectedName = product.ProductName.ToSeoUrl();
       string actualName = (productName ?? "").ToLower();

       // permanently redirect to the correct URL
       if( expectedName != actualName )
       {
           return RedirectToActionPermanent("Index", "Products", new { id = product.ProductID, productName = expectedName });
       }

       return View(product);
   }
}

This updated controller will do an HTTP 301 redirect if the product name in the URL does not match what it should be, or if it wasn't provided at all. A 301 redirect will tell a search engine to permanently re-index the content. If the user types http://www.northwind.com/products/3 or http://www.northwind.com/products/3/aniseed or any other URL other than http://www.northwind.com/products/3/aniseed-syrup then it will automatically redirect them to the correct one.

The final piece to wire this all up is to make sure your views are creating the proper links. We don't want the requests to redirect by default, otherwise every request will make two calls to the database. Here I am going to use the new MVC 3 View Engine Razor, but it could be done just as easily using the Web Forms View Engine.

@model IEnumerable
@using Mvc.Helpers







  @foreach( var product in Model )
  {




  }
        Edit      Product Name                    
@Html.ActionLink("Edit", "Details", new { id = product.ProductID,
productName = product.ProductName.ToSeoUrl() })         @product.ProductName  

 
That's all you need to do. Create an ActionLink and make sure you pass the productName value by calling our ToSeoUrl() helper. Hopefully you found this technique as helpful as I did.

Recent Blog Posts

lunavi logo alternate white and yellow
3.13.2025
3
.
12
.
2025
Unlocking the Power of Azure Managed Services with Lunavi

Cloud computing has become the backbone of modern business, offering agility, scalability, and cost efficiency. But managing cloud environments while keeping costs under control and security airtight? That’s a challenge. Azure Managed Services streamline cloud operations, helping businesses optimize spending, enhance security, and future-proof applications. Lunavi provides the expertise and tools to make it happen—so you can focus on growth instead of IT headaches.

Learn more
lunavi logo alternate white and yellow
2.11.2025
2
.
7
.
2025
The Future of Test Automation: Key Trends Shaping 2025 and Beyond

Software testing has gone from a chore to a game-changer, thanks to automation. But in 2025, sticking to old methods means falling behind. Stay ahead by embracing the future of test automation—let’s explore the key trends shaping what’s next.

Learn more
lunavi logo alternate white and yellow
2.11.2025
1
.
23
.
2025
The Importance of Cross Browser Testing

Making sure users have a smooth experience across all these platforms is crucial for businesses to stay competitive. Cross-browser testing is now a key part of modern development. It helps teams find and fix problems like layout issues, broken features, or slow performance before users are affected. Let’s look at why cross-browser testing matters and explore tools that make it easier to get the job done.

Learn more