And*_*rey 33 asp.net routing webforms url-routing
我在Global.asax中定义了几条路线;
当我在页面上时,我需要弄清楚当前路由的路由名称是什么,因为路由名称驱动我的站点菜单.
如何才能做到这一点?
Haa*_*ked 23
不幸的是,由于名称不是Route的属性,因此无法获取路径的路径名称.将路由添加到RouteTable时,该名称将用作路径的内部索引,并且永远不会公开.
有一种方法可以做到这一点.
当您注册一个路由,路由名称的路线上设置的DataToken并用它来过滤路由.
做#1,最简单的方式是可能会写自己的扩展方法映射路线.
Sim*_*ver 11
如果您正在使用一小部分重要路线,您需要检查(特殊情况或两个),您可以这样做:
if (routeData.Route == RouteTable.Routes["gallery-route"])
{
// current route is 'gallery-route'
}
Run Code Online (Sandbox Code Playgroud)
需要路由名称的常见原因是出于调试目的.下面是一种快速而肮脏的方法 - 但您需要将每个路由名称添加到名称数组中.应该可以正常进行调试 - 特别是如果代码在生产期间没有运行.
// 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
}
Run Code Online (Sandbox Code Playgroud)
对于超出此范围的任何事情,您应该花费@haacked解决方案所需的(最少)时间.
kma*_*man 11
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;
}
Run Code Online (Sandbox Code Playgroud)
所以现在在Global.asax.cs中注册路由时,而不是像routes.MapPageRoute(...)那样 - 而是使用扩展方法并执行routes.MapPageRouteWithName(...)
然后,当您想要检查您所在的路线时,只需执行Page.RouteData.GetRouteName()
而已.没有反射,并且对"route-name"的唯一硬编码引用是在两个扩展方法中(如果你真的想要,可以用const替换).
这是@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;
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个简单的剃刀.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>
Run Code Online (Sandbox Code Playgroud)
我会对Simon_Weaver的答案进行投票,但遗憾的是我刚加入并且没有声誉点.
添加他的答案,因为它正是我所寻找的,这就是我的方式:
我有一个公共枚举"PageRouteTable":
public enum PageRouteTable
{
// -- User Area
UserArea_Locations,
UserArea_Default,
UserArea_PasswordReset,
UserArea_Settings,
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
我在构建路径时使用此枚举:
/* -- User Area Routes -- */
routes.MapPageRoute(PageRouteTable.UserArea_Default.ToString(), "home", "~/UserArea/Default.aspx");
Run Code Online (Sandbox Code Playgroud)
然后我创建了一个Page扩展方法:
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;
}
Run Code Online (Sandbox Code Playgroud)
现在,在我的页面中,我可以简单地使用开关来对其进行操作:
PageRouteTable? currentRoute = this.CurrentRoute();
if (currentRoute.HasValue) {
switch(currentRoute.Value) {
case PageRouteTable.UserArea_Default:
// Act accordingly
break;
.
.
.
}
}
Run Code Online (Sandbox Code Playgroud)
我也有显式定义变量的好处,不必担心对字符串进行编码.这为我节省了大量的维护麻烦.
- 快乐的编码.
归档时间: |
|
查看次数: |
28995 次 |
最近记录: |