我在Global.asax中定义了几条路线;
当我在页面上时,我需要弄清楚当前路由的路由名称是什么,因为路由名称驱动我的站点菜单。
如何做到这一点?
答案 0 :(得分:21)
不幸的是,无法获取路线的路线名称,因为该名称不是路线的属性。将路由添加到RouteTable时,该名称将用作路径的内部索引,并且永远不会暴露。
有一种方法可以做到这一点。
注册路线时,请在路线上设置包含路线名称的DataToken,并使用该路径过滤路线。
执行#1的最简单方法是编写自己的扩展方法来映射路由。
答案 1 :(得分:10)
如果您正在处理一小部分重要路线,您需要检查(特殊情况或两个),您可以这样做:
if (routeData.Route == RouteTable.Routes["gallery-route"])
{
// current route is 'gallery-route'
}
需要路由名称的常见原因是出于调试目的。下面是一种快速而肮脏的方法 - 但您需要将每个路由名称添加到名称数组中。应该可以用于调试 - 特别是如果代码在生产期间没有运行。
// quick and dirty way to get route name
public string GetRouteName(RouteData routeData)
{
foreach (string name in new [] { "gallery-route",
"products-route",
"affiliate-route",
"default" })
{
if (routeData.Route == RouteTable.Routes[name])
{
return name;
}
}
return "UNKNOWN-ROUTE"; // or throw exception
}
对于超出此范围的任何事情,您应该花费@haacked解决方案所需的(最少)时间。
答案 2 :(得分:9)
FWIW,由于@Simon_Weaver显示的扩展和示例是基于MVC的,并且帖子是用WebForms标记的,我以为我会分享基于WebForms的扩展方法:
public static void MapPageRouteWithName(this RouteCollection routes, string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess = true,
RouteValueDictionary defaults = default(RouteValueDictionary), RouteValueDictionary constraints = default(RouteValueDictionary), RouteValueDictionary dataTokens = default(RouteValueDictionary))
{
if (dataTokens == null)
dataTokens = new RouteValueDictionary();
dataTokens.Add("route-name", routeName);
routes.MapPageRoute(routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, defaults, constraints, dataTokens);
}
public static string GetRouteName(this RouteData routeData)
{
if (routeData.DataTokens["route-name"] != null)
return routeData.DataTokens["route-name"].ToString();
else return String.Empty;
}
所以现在在Global.asax.cs中注册你的路线,而不是做类似的路线.MapPageRoute(...) - 而是使用扩展方法并做routes.MapPageRouteWithName(...)< / p>
然后,当您想要检查您所处的路线时,只需执行Page.RouteData.GetRouteName()
那就是它。没有反思,唯一的硬编码引用&#34; route-name&#34;在两个扩展方法中(如果你真的想用它可以用const替换)。
答案 3 :(得分:7)
这是@haacked建议的实现 - 还有一个简单的'razor'表来显示路径数据。
注意:您可能没有意识到所有标准的“MapRoute”方法实际上都是扩展方法。因此我们不能使用相同的名称。我刚才称它为'MapRoute2',因为现在我能想到的就是它。
您必须通过调用MapRoute2替换对MapRoute的所有调用,不要忘记所有AreaRegistration文件以及global.asax.cs
扩展方法:
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;
}
}
这是一个简单的剃刀.cshtml文件,用于显示路由信息:
<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>
答案 4 :(得分:6)
我会对Simon_Weaver的回答进行投票,但遗憾的是我刚刚加入并没有声誉点。
添加他的答案,因为它正是我所寻找的,这就是我的方式:
我有一个公共枚举“PageRouteTable”:
public enum PageRouteTable
{
// -- User Area
UserArea_Locations,
UserArea_Default,
UserArea_PasswordReset,
UserArea_Settings,
.
.
.
}
在构建路径时使用此枚举:
/* -- User Area Routes -- */
routes.MapPageRoute(PageRouteTable.UserArea_Default.ToString(), "home", "~/UserArea/Default.aspx");
然后我创建了一个页面扩展方法:
public static PageRouteTable? CurrentRoute(this Page p)
{
string[] pageRoutes = Enum.GetNames(typeof (PageRouteTable));
foreach (string pageRoute in pageRoutes)
{
if (p.RouteData.Route == RouteTable.Routes[pageRoute])
{
return (PageRouteTable)Enum.Parse(typeof (PageRouteTable), pageRoute);
}
}
return null;
}
现在在我的页面中,我可以简单地使用开关来对其采取行动:
PageRouteTable? currentRoute = this.CurrentRoute();
if (currentRoute.HasValue) {
switch(currentRoute.Value) {
case PageRouteTable.UserArea_Default:
// Act accordingly
break;
.
.
.
}
}
我也有明确定义的变量的好处,不必担心对字符串进行编码。这为我节省了大量的维护麻烦。
- 快乐的编码。
答案 5 :(得分:3)
RouteCollection维护一个名为routes的私人字典。
可以通过
哄骗路线名称以下扩展方法遵循以下流程:
public static string Name(this RouteBase original)
{
var routes = System.Web.Routing.RouteTable.Routes;
if (routes.Contains(original))
{
var namedMapField = routes.GetType().GetField("_namedMap", BindingFlags.NonPublic | BindingFlags.Instance);
var namedMap = namedMapField.GetValue(routes) as Dictionary<string, RouteBase>;
var query =
from pair in namedMap
where pair.Value == original
select pair.Key;
return query.Single();
}
return string.Empty;
}
答案 6 :(得分:2)
对于C#,您可以声明您的路线:
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" } });
然后在您需要路线的方法中,您可以调用以下内容:
var x = Page.RouteData.Values["Section"].ToString();
然后您将在global.asax中设置一个字符串,然后根据需要使用。
答案 7 :(得分:1)
我一直面临同样的困境,我得出的结论是,遗憾的是,似乎没有办法找出ASP.NET选择使用哪条路径(按名称)。
您似乎只能通过路线中可能存在的参数名称来计算出来 - 这些参数会显示在RouteData.Values
词典中。
如果有人知道某种方式可以获得ASP.NET为给定URL选择的路由的实际名称,我也有兴趣知道如何自己这样做!
答案 8 :(得分:1)
您可以添加每个路线参数,而不必将此参数添加到您的网址中: 您可以将路径名称作为参数放在thisGlobal.asax:
中 routes.MapPageRoute("Page",
"Page-{ID}",
"~/Item_show.aspx", false, new RouteValueDictionary{ { "RouteName" , "Page" }});
并在您的页面中访问它:
if (RouteData.Values["RouteName"] != null)
{
if (RouteData.Values["RouteName"].ToString() == "Page")
{
Response.Write(RouteData.Values["RouteName"]);
}
}
最好的方法并不难。
答案 9 :(得分:0)
我实现的一个简单方法是为.MapPageRoute方法的'defaults'参数提供一个命名键。使用常量作为默认值,您可以像往常一样将它从Page.RouteData.Values集合中拉出来。
示例(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")
给了'统计'