A: 

I had a similar issue from what I've learned is the routing takes the last route

So its using your hash route instead so thus its putting ""

Basically you could get rid of that hash route and just have this

 routes.MapRoute(            "Default",                                              // Route name            "{controller}/{action}/{hash}",                           // URL with parameters            new { controller = "Home", action = "Index", hash="" }  // Parameter defaults        );

It would accomplish the same thing, and when the hash isn't provided it wouldn't matter

dswatik
But what if I want them to be able to just type www.mysite.com/hashgoeshere ?
Mithrax
ie, www.mysite.com/fghas82
Mithrax
that will still work
dswatik
+2  A: 

The problem is that you don't have a route that matches the route values (controller = Home, action = Create).

You have two routes, one is the empty string (no parameters), which matches Controller = "Home", Action = "Index". The other is your hash route, which matches Controller = "Home", Action = "RequestLink". So, when ASP.Net Routing goes to build a URL from the route values you're providing, it can't find one (since none of them have the "{controller}" and "{action}" parameters).

The simplest solution, in this case, is to create a direct route to the "Create" action, so that you can still use your "hash" route. Put this at the top of your RegisterRoutes method. NOTE: Order does matter! ASP.Net Routing checks each route, in the order added, until it finds a match.

routes.MapRoute(
        "Create",                                              // Route name
        "Create",                           // URL with parameters
        new { controller = "Home", action = "Create" }  // Parameter defaults
    );

Since you have that "hash" route, you can't really use the default "{controller}/{action}/{id}" technique, since the "hash" value would be consider a valid Controller name. So, if someone requested: http://www.mysite.com/fjhas82, MVC would look for a Controller called "fjhas82" and complain that it couldn't find it. Unfortunately, this means you have to manually add new routes for each new Controller Action (like I showed above), which is a pain.

The best solution (in my opinion) is to use Regex Constraints: If your hashes have a very well-defined format (say: 5 letters followed by 2 numbers, or "_" followed by any alpha-numeric characters, etc.), or if you're willing to impose such a format, you can use the Regex constraints supported by ASP.Net Routing. Then, you'd only need these two routes

routes.MapRoute(
        "Redirect",
        "{hash}",
        new { controller = "Home", action = "RequestLink" },
        new { hash = @"[a-zA-Z]{5}[0-9]{2}" } // Regex Constraints
    );

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

Under these routes, if MVC sees a controller name like: "Home", it will check the first route, find that it doesn't match the regular expression, and move to the next one. NOTE: My Regular Expression syntax may be a bit rusty, so I'd use something like http://regexpal.com/ to test a Regex first, to make sure it works with your hashes and controller names.

Hope that helps, I know I wrote a lot, but MVC is so flexible, you can do things in so many different ways!

anurse