R – ASP.Net MVC Routing – using same pattern for different controllers

asp.net-mvcrouting

Say I have an ASP.Net MVC site with products and categories, and I want these urls…

Products:

  • Fruitshop.com/super-tasty-apple
  • Fruitshop.com/squishy-orange
  • Fruitshop.com/worm-infested-apple
  • Fruitshop.com/megaorange

Categories:

  • Fruitshop.com/apples
  • Fruitshop.com/oranges

For each product/category in the database, I save the slug (or whatever you call it), like "super-delicous-apple" or "apples".

There is no pattern or regular expression(that I can see, anyway), that allow me to determine just by looking at the url, if it is a product or a category. I need to look in the database to know.

What would be a good way to approach this?

  1. At application startup, register the route of every single product and category
  2. Create some code that handles the requests, and look up the slug in the database
  3. ??

Nevermind caching, refreshing routing-table etc for now. 🙂

Feel free to edit my question title, if you feel there is a more appropriate title for this question – this was the best I could come up with.

Best Answer

I like your approach #2 more so than #1. I think you could get away with creating a single route that goes to a SlugHandler action in a SlugController (or whatever else you want to call these). You would need only one route for this.

Your SlugHandler action would then accept a slug string, then call upon a method to determine whether the slug is a category or a product. (You did say these were unique, yes? i.e., not possible to have same slug for BOTH a product and a category.) From there, you could call upon the appropriate Product or Category action method, passing along the slug string.

Some code fragments follow:

internal enum SlugType
{
    Category,
    Product
}

private SlugType DetermineSlugTypeFromSlugName(string slug)
{
    // some database magic happens here to return appropriate SlugType
}

public ActionResult SlugHandler(string slug)
{
    SlugType slugType = DetermineSlugTypeFromSlugName(slug);
    switch (slugType)
    {
        case SlugType.Category:
            return Category(slug);
        case SlugType.Product:
            return Product(slug);
        default:
            return SomeErrorAction();
    }
}

Best of luck!
-Mike