Подтвердить что ты не робот

Как получить имя маршрута из RouteData?

У меня есть несколько маршрутов, определенных в моем Global.asax;

Когда я нахожусь на странице, мне нужно выяснить, что такое имя маршрута текущего маршрута, потому что имя маршрута управляет моим меню сайта.

Как это можно сделать?

4b9b3361

Ответ 1

К сожалению, невозможно получить имя маршрута маршрута, потому что имя не является свойством маршрута. При добавлении маршрутов в RouteTable имя используется как внутренний индекс для маршрута и никогда не отображается.

Есть один способ сделать это.

Когда вы регистрируете маршрут, установите DataToken на маршруте с именем маршрута и используйте его для фильтрации маршрутов.

Самый простой способ сделать # 1 - это, вероятно, написать собственные методы расширения для маршрутизации маршрутов.

Ответ 2

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, когда вы регистрируете свои маршруты, вместо того, чтобы делать как route.MapPageRoute(...) - вместо этого используйте метод расширения и делаете маршруты. MapPageRouteWithName (...)

Затем, когда вы хотите проверить, на каком маршруте вы находитесь, просто сделайте Page.RouteData.GetRouteName()

Что это. Отсутствие отражения, и единственные жестко закодированные ссылки на "имя маршрута" находятся в двух методах расширения (которые можно было бы заменить на const, если вы действительно этого хотели).

Ответ 3

Если вы работаете с небольшим подмножеством важных маршрутов, вам нужно проверить (специальный случай или два), вы можете просто сделать это:

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.

Ответ 4

Здесь реализовано предложение @haacked - также с помощью простой таблицы "бритвы" для отображения данных маршрута.

Примечание. Возможно, вы не поняли, что все стандартные методы "MapRoute" на самом деле являются методами расширения. Поэтому мы не можем использовать одно и то же имя. Я только что назвал его "MapRoute2", потому что сейчас это все, о чем я могу думать.

Вы должны заменить все вызовы на MapRoute вызовом MapRoute2, не забудьте все файлы 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;
    }
}

Вот простой файл 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>

Ответ 5

Я бы проголосовал за 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;
        .
        .
        .
    }
}

У меня также есть преимущество явно определенных переменных и не нужно беспокоиться о кодировании строк. Это экономит мне массу головных болей при обслуживании.

- счастливое кодирование.

Ответ 6

RouteCollection поддерживает частный словарь именованных маршрутов.

Имена маршрутов можно уговорить на

  • с использованием отражения для получения значения частного поля и
  • запрос словаря для элемента, значением которого является маршрут.

Ниже описан метод расширения:

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;
}

Ответ 7

В С# вы можете объявить свои маршруты следующим образом:

        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, чтобы затем использовать по мере необходимости.

Ответ 8

Я столкнулся с одной и той же дилеммой, и я пришел к выводу, что, к сожалению, не существует способа узнать, какой маршрут (по его названию) выбрал ASP.NET для использования.

Похоже, вы можете понять это только по именам параметров, которые могут существовать на вашем маршруте, - они будут отображаться в словаре RouteData.Values.

Если кто-то знает способ как-то добраться до фактического имени маршрута, выбранного ASP.NET для заданного URL-адреса, мне тоже будет интересно узнать, как это сделать!

Ответ 9

Вы можете добавить все параметры маршрута и не обязательно, чтобы эти параметры были в вашем 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"]);

               }  

           }

Лучший способ - не сложно.

Ответ 10

Простым подходом, который я реализовал, является предоставление именованного ключа для параметра "defaults" метода .MapPageRoute. Используйте константу по умолчанию, и вы можете вытащить ее из коллекции Page.RouteData.Values ​​так же, как обычно.

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") дает мне "статистику"