1

I am keen to know how Stackoverflow rewrites a URL.
For example

http://stackoverflow.com/questions/7325278/group-by-in-linq
http://stackoverflow.com/questions/7325278/
http://stackoverflow.com/questions/7325278
http://stackoverflow.com/questions/7325278/random-blah

All of them redirect to http://stackoverflow.com/questions/7325278/group-by-in-linq

I have to do something very similar, but should I hit the database to get redirect URL against a key(question id in this case), or should I maintain dictionary in my app or is there a better way to do it?
Would be great to know how SO does it.

Update:
The user curated URLs are all 301d to canonical URL. Is it efficient to redirect from the action, as pointed out in one of the answers?

Null Head
  • 2,877
  • 13
  • 61
  • 83

1 Answers1

2

It is not about IIS URL rewriting. It is about ASP.NET routing.
It looks definitely like the string after question ID is simply ignored. Since it works without this string argument, it is, probably, used for user's convenience.

In ASP.NET MVC you have routes. If you don't know much about it - read these two articles: at MSDN, at ASP.NET.

By default, you have the following RouteConfig:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Welcome", action = "Index", id = UrlParameter.Optional }
);

It means that if you have an action like:

public class InformationController : Controller
{    
    public ActionResult Get(int id)
    {
        // ...
    }
}

Then you can access it the following way:

http://yourwebsite.com/Information/Get/7325278

which is the same as

http://yourwebsite.com/Information/Get/?id=7325278

If you want an additional argument, you can change your route to work with 2, 3 or more arguments.

Then, you will make a

http://yourwebsite.com/Information/Get/7325278/group-by-in-linq

which is an equivalent to

http://yourwebsite.com/Information/Get/?id=7325278&someParam=group-by-in-linq

Here is the StackOverflow topic about routes with multiple arguments.

Let's suppose you now have multiple arguments routing. Now, you can describe any logic in your action. For example, you can use this param in your code or you can ignore this second argument and redirect to necessary URL (how StackOverflow does).
Maybe, my pseudo-pseudo-code will help you:

public ActionResult Get(int id, string unnecessaryString)
{
    var question = questionsDbProvider.getById(id);
    if (question.ShortUrlText == unnecessaryString)
        return RedirectToAction("Get", new { 
            id = id, 
            unnecessaryString = question.ShortUrlText 
        });
}

Such action code will check if it's second argument is correct and redirect to correct otherwise.
301 redirecting is exactly what StackOverflow does to make it work this way. You can check it in Network tab of browser's developer tools.

Community
  • 1
  • 1
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
  • Yeah, I am aware of this but as pointed out in my question, I dont want to hit db everytime the same key is used but with different helpText (assuming key is the question number and helpText is context text for user) especially when I have cached the page. I will update the question to consider about caching. – Null Head Jul 01 '15 at 06:59
  • @NullHead 301 redirects is exactly what StackOverflow does to make it work this way. You can check it in Network tab of browser's developer tools. You can use ASP.NET cache to avoid unnecessary requests. – Yeldar Kurmangaliyev Jul 01 '15 at 07:19
  • I mentioned that in my update. My question is, how efficient is it to do a 301 from Action? – Null Head Jul 01 '15 at 20:43