ASP Routing
MSDN, Asp.Net. For debugging, Install-Package routedebugger
In .net 4+ with a Microsoft IIS patch will make routing work, but otherwise you may have to set runAllManagedModulesForAllRequests (NB: this may mean static .css and .js are authenticated, and the login page becomes a little plain!).
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
In Webforms
See MSDN
In MVC
Routes are defined in from global.asax Application_start: RegisterRoutes(RouteTable.Routes);
Mvc uses the route conventions of {controller} and {action}, with defaults as required.
routes.MapRoute(
"Yearly",
"{year}/{controller}/{action}/{id}",
new { year = DateTime.Now.Year, controller = "Home", action = "IndexByYear", id = UrlParameter.Optional }
);
...will map http://site/1983/Products/display/123 to ProductsController (implementing IController) method Display, passing in parameter with name id=123 and year with default 2010.
Route Defaults and Constraints
routes.MapRoute(
"Yearly",
"{year}/{controller}/{action}/{id}",
new { year = DateTime.Now.Year, controller = "Home", action = "IndexByYear", id = UrlParameter.Optional },
new { year = @"\d{4}" });
Default/ 404 routes
Remember this should always be the last route.
routes.MapRoute("Error",
"{*url}",
new { controller = "Error", action = "404" }
);
*Catchalls
//mydomain/Product/Index/A/Extra/More will invoke action
// public ActionResult Index(string id, string catchall)
// id = "A" and catchall = "Extra/More".
routes.MapRoute("MyCatchallRoute",
"{controller}/{action}/{id}/{*catchall}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
Duplicate controller names
If you have two "HomeControllers" in different namespaces you have a YSOD error. So add two routes and specify the namespaces (the namespace string array is not a hierarchy)
routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional },
new[] { "MyPriorityNamespace.Controllers" });
To stop searches (first match only)
//To stop searching all namespaces
myRoute.DataTokens["UseNamespaceFallback"] = false;
In controllers
Controllers have a RedirectToAction() method.
In Views
use Html.ActionLink or Html.RouteLink
<li><a href="/Home/About">Go to About (manual link)</a></li>
<li><a href="@Url.ActionLink("About", "Home")">Go to About (URL link)</a></li>
ActionLinks
<li>In another controller</li>
<li>@Html.ActionLink("Go to LogOn", "LogOn", "Account")</li>
<li>Below renders as /Home/Details/2 . The final null is important otherwise you get /Home/Details?Length=4</li>
<li>@Html.ActionLink("Go to Details with parameter", "Details", "Home", new { id = 2 }, null)</li>
RouteLinks
<li>@Html.RouteLink("Go to Logon", new { controller = "Account", action = "Logon" })</li>
<li>@Html.RouteLink("Use named route","SpecialRoute")</li>
<li>Areas</li>
<li>@Html.ActionLink("Go to Admin area", "Index", "User", new { area = "Admin" }, null)</li>
WebAPI
WebApi routes in javascript (assuming default route name)
var url = '@Url.HttpRouteUrl("DefaultApi", new { controller="Data"} )';
WebApi routes via html anchor (assuming default route name). Note the "httproute=true".
<p>@Html.RouteLink("Call my api", "DefaultApi", new { controller = "Values", httproute= true, id = 1 }, new { @class = "btn btn-info" }).</p>
Areas
AreaRegistration happens before other routes, so the areaName (first part) is matched before the other routes. Remember for actions to areas to specify the area (or "" for top level).
@Html.ActionLink("Go to Admin area", "Index", "User", new { area = "Admin" }, null)
@Html.ActionLink("Go to Home", "Index", "Home", new { area = "" }, null)