Asp.net 如何从RouteData获取路线名称?
我在我的Global.asax中定义了多条路线 当我在一个页面上时,我需要找出当前路由的路由名称,因为路由名称驱动我的站点菜单Asp.net 如何从RouteData获取路线名称?,asp.net,routing,webforms,url-routing,Asp.net,Routing,Webforms,Url Routing,我在我的Global.asax中定义了多条路线 当我在一个页面上时,我需要找出当前路由的路由名称,因为路由名称驱动我的站点菜单 如何做到这一点?我一直面临着同样的困境,我得出的结论是,不幸的是,似乎没有办法找出ASP.NET选择了哪条路线(按其名称) 似乎您只能通过路由中可能存在的参数的名称来确定,这些参数将显示在RouteData.Values字典中 如果有人知道如何获得ASP.NET为给定URL选择的路线的实际名称,我也很想知道自己如何做到这一点 不幸的是,无法获取路由的路由名称,因为该名称
如何做到这一点?我一直面临着同样的困境,我得出的结论是,不幸的是,似乎没有办法找出ASP.NET选择了哪条路线(按其名称) 似乎您只能通过路由中可能存在的参数的名称来确定,这些参数将显示在
RouteData.Values
字典中
如果有人知道如何获得ASP.NET为给定URL选择的路线的实际名称,我也很想知道自己如何做到这一点 不幸的是,无法获取路由的路由名称,因为该名称不是路由的属性。将路由添加到RouteTable时,该名称将用作路由的内部索引,并且从不公开 有一种方法可以做到这一点 注册路由时,使用路由名称在路由上设置DataToken,并使用该名称筛选路由
最简单的方法是为映射路由编写自己的扩展方法。如果您使用的是需要检查的重要路由的一小部分(一两个特殊情况),您可以执行以下操作:
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解决方案所需的(最少)时间 这里是@haacked建议的一个实现——还有一个简单的“razor”表来显示路线数据 注意:您可能没有意识到所有标准的“MapRoute”方法实际上都是扩展方法。因此,我们不能使用相同的名称。我刚刚把它叫做“地图路线2”,因为现在我所能想到的就是这些 您必须将对MapRoute的所有调用替换为对MapRoute2的调用,不要忘记所有区域注册文件以及global.asax.cs 扩展方法:
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;
}
下面是一个简单的razor.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>
路由密钥
价值
路线名称
@ViewContext.RouteData.DataTokens[“路由名称”]
@foreach(ViewContext.RouteData.Values中的变量路由)
{
-@route.Key
@(route.Value???)
}
@foreach(ViewContext.RouteData.DataTokens.Where中的var route(x=>x.Key!=“路由名称”))
{
@route.Key
@(route.Value???)
}
我会投票支持西蒙·韦弗的答案,但不幸的是,我刚刚加入,没有这样做的声望点
再加上他的回答,因为这正是我想要的,我的做法如下:
我有一个公共枚举“PageRouteTable”:
我在构建路由时使用此枚举:
/* -- 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;
.
.
.
}
}
我还有显式定义变量的好处,不必担心根据字符串编码。这使我在维护时省去了很多麻烦
--快乐编码。维护命名路由的私有字典
路由名称可以通过
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;
}
公共静态字符串名称(此RouteBase原始)
{
var routes=System.Web.Routing.RouteTable.routes;
if(路由包含(原件))
{
var namedMapField=routes.GetType().GetField(“_namedMap”,BindingFlags.NonPublic | BindingFlags.Instance);
var namedMap=namedMapField.GetValue(路由)作为字典;
变量查询=
来自namedMap中的pair
其中pair.Value==original
选择pair.Key;
返回query.Single();
}
返回字符串。空;
}
我实现的一个简单方法是为.MapPageRoute方法的'defaults'参数提供一个命名键。使用一个常量作为默认值,您可以按照正常方式将其从Page.RouteData.Values集合中拉出
示例(vb.net)
Page.RouteData.Values(“section”)
为我提供了“stats”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(…)
然后,当您想检查您所在的路由时,只需执行Page.RouteData.GetRouteName()
就这样。没有反射,对“route name”的唯一硬编码引用是在两个扩展方法中(如果您真的愿意,可以用const替换)。对于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中设置一个字符串,然后根据需要使用。您可以添加每个路由参数,但不必在Url中添加这些参数: 您可以将路由名称作为参数,如inGlobal.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"]);
}
}
最好的方法不是艰难的方法。是的,那太糟糕了!他们有一张私人地图,上面有名字和路线,但没有办法公开:(事实上,哈克德的解决方案非常有效,现在在我的生产现场:)@Andrey:ye
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"]);
}
}