I have several routes defined in my Global.asax;
When I\'m on a page I need to figure out what is the route name of the current route, because route name drives my site
A simple approach that I've implemented is to supply a named key for the 'defaults' param of the .MapPageRoute method. Use a constant for the default, and you can pull it out of the Page.RouteData.Values collection the same way you would normally.
example (vb.net)
routes.MapPageRoute("league-division-stats", "{league}/{division}/stats", "~/routes/league-division-stats.aspx", False, New RouteValueDictionary(New With {.section = "stats"}))
Page.RouteData.Values("section")
gives me 'stats'
Here's an implementation of @haacked's suggestion - with also a simple 'razor' table to display route data.
Note: You may not have realized that all the standard 'MapRoute' methods are actually extension methods. Therefore we cannot use the same name. I've just called it 'MapRoute2', because right now thats all I can think of.
You must replace all calls to MapRoute with a call to MapRoute2, don't forget all AreaRegistration files as well as global.asax.cs
Extension method:
public static class RouteNameExtensions
{
// RouteCollection
public static Route MapRoute2(this RouteCollection routes, string name, string url)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url));
}
public static Route MapRoute2(this RouteCollection routes, string name, string url, object defaults)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults));
}
public static Route MapRoute2(this RouteCollection routes, string name, string url, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, namespaces));
}
public static Route MapRoute2(this RouteCollection routes, string name, string url, object defaults, object constraints)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, constraints));
}
public static Route MapRoute2(this RouteCollection routes, string name, string url, object defaults, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, namespaces));
}
public static Route MapRoute2(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, constraints, namespaces));
}
// AreaRegistrationContext
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url));
}
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url, object defaults)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults));
}
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, namespaces));
}
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url, object defaults, object constraints)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, constraints));
}
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url, object defaults, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, namespaces));
}
public static Route MapRoute2(this AreaRegistrationContext routes, string name, string url, object defaults, object constraints, string[] namespaces)
{
return AddRouteNameDataToken(name, routes.MapRoute(name, url, defaults, constraints, namespaces));
}
private static Route AddRouteNameDataToken(string name, Route route)
{
route.DataTokens["route-name"] = name;
return route;
}
}
Here's a simple razor .cshtml file I'm using to display routing information:
<table class="basic-table">
<tr>
<th>Route Key</th>
<th>Value</th>
</tr>
<tr>
<td><strong>Route name</strong></td>
<td>@ViewContext.RouteData.DataTokens["route-name"]</td>
</tr>
@foreach (var route in ViewContext.RouteData.Values)
{
<tr>
<td>- @route.Key</td>
<td>@(route.Value ?? "<null>")</td>
</tr>
}
@foreach (var route in ViewContext.RouteData.DataTokens.Where(x=>x.Key != "route-name"))
{
<tr>
<td><strong>@route.Key</strong></td>
<td>@(route.Value ?? "<null>")</td>
</tr>
}
</table>
For C# you can declare your routes like so:
routeCollection.MapPageRoute("RouteForProduct", "Product/{ProductName}", "~/IRShop.aspx", false, new RouteValueDictionary { { "Section", "product" } });
routeCollection.MapPageRoute("RouteForProductList", "ProductList/{CatName}", "~/IRShop.aspx", false, new RouteValueDictionary { { "Section", "productlist" } });
routeCollection.MapPageRoute("RouteForContentList", "Content/{PageName}", "~/IRShop.aspx", false, new RouteValueDictionary { { "Section", "content" } });
Then in your method where you need the route you can then call the following:
var x = Page.RouteData.Values["Section"].ToString();
And you will have a string set in your global.asax to then use as you need.
I have been facing the same dilemma, and I came to the conclusion that unfortunately, there doesn't seem to be a way to find out which route (by its name) the ASP.NET has picked for usage.
It seems you can only figure that out by the names of the parameters that might exist in your route - those will show up in the RouteData.Values
dictionary.
If someone knows a way to somehow get at the actual name of the route picked by ASP.NET for a given URL, I'd be interested to know how to do that myself, too!