Search code examples
asp.net-mvcasp.net-mvc-routingpermalinks

Wordpress like dynamic permalinks in ASP.NET MVC2/3 or ASP.NET 4.0


Scenario:

There are two entities say 'Books' and 'Book Reviews'. There can be multiple books and each book can have multiple reviews.

Each review and book should have a separate permalink. Books and Reviews can be added by users using separate input forms. As soon as any book/review is added it should be accessible by its permalink.

Anyone can point me in the right direction on how should this be implemented?


Solution

  • Url routing will handle this out of the box with no additional real work required.

    Just create a Books or BookReviews controller. Create a action method that takes an Id

    You will have basic permalinks like /Books/Details/1 and /BookReviews/Details/4

    If your happy with permalinks like that, then you are good to go. :)

    However, if you want to take it further and make it even more search engine friendly with a little bit more work......

    First you should create or find a simple "slug" encoder, which will take a string (perhaps the title of the book or reviewer) and encode any non-alphanumeric characters into a - or similar. URL Slugify algorithm in C#?

    Now we can create a route like

    Books/{title}-{id}

            routes.MapRoute(
                "BooksSeoRoute", 
                "Books/{slug}-{id}", 
                new { controller = "Books", action = "Details" } // Parameter defaults
            );
    

    So we end up with permalinks that look like: Books/The-Title-Of-The-Book-38

    For the book reviews, you might want to have a "nested" approach so you could use

        routes.MapRoute(
                "BookReviewsSeoRoute", 
                "Books/{book-slug}/{slug}-{id}", 
                new { controller = "BookReviews", action = "Details" } // Parameter defaults
            );
    

    Books/The-The-Of-The-Book-38/Review-by-John-Smith-24

    You can either add a slug field to your models/entites/database, or you can just add a getter that will dynamically generate it from your title/author

    ie

    public class Book {
    
    public string Id {get;set;}
    
    public string Title {get;set;}
    
    public string Slug
    get
    {
     return SlugEncoder.EncodeString(this.Title);
    }
    }
    

    In your views

    =Html.ActionLink("Permalink","Details","Book",new{@Id=Model.Id, @Slug=Model.Slug})