how to implement url rewriting similar to SO

I need to implement SO like functionality on my asp.net MVC site.

For example when user go to https://stackoverflow.com/questions/xxxxxxxx

after loading the subject line is concatenated with the url and url becomes like this https://stackoverflow.com/questions/xxxxxxxx/rails-sql-search-through-has-one-relationship

Above "/rails-sql-search-through-has-one-relationship " part is added to the url.

In webforms it's simple, I could just use url rewriting. But not sure how to accomplish this in MVC

The following line is from Global.asax file

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Account", action = "LogOn", id = UrlParameter.Optional } // Parameter defaults
        );

the string that I need to concatenate is in my database so it fetches from there. How can I accomplish this?


This is called a slug route. One way to achieve this is to define a route with an optional slug parameter, and in the controller method check if the parameter has been provided

routes.MapRoute(
    name: "Question",
    url: "Question/{id}/{slug}",
    defaults: new { controller = "Question", action = "Details", slug = UrlParameter.Optional }
);

Then in QuestionController (assumes an id will always be provided)

public ActionResult Details (int id, string slug)
{
    if (string.IsNullOrEmpty(slug))
    {
        // Look up the slug in the database based on the id, but for testing
        slug = "this-is-a-slug";
        return RedirectToAction("Details", new { id = id, slug = slug });
    }
    var model = db.Questions.Find(id);
    return View(model);
}

You are looking for a custom route. If you look closely, SO doesn't care about the text part of the URL. So:

 http://stackoverflow.com/questions/xxxxxxxx/rails-sql-search-through-has-one-relationship
 AND
 http://stackoverflow.com/questions/xxxxxxxx/

Will both work. You can easily do that with something like:

routes.MapRoute(
    "Question",
    "questions/{id}/{title}",
    new { controller = "Question", action = "Details" });

The trick is add the "slug" at the end when you create links:

@Html.RouteLink(
    "Read more.",
    "Question",
    new { id = question.Id, title = Slugger.ToUrl(question.Title) })