Отримати поточну назву області у режимі перегляду чи контролера


126

Як отримати назву поточної області у вікні чи контролері?

Чи є щось подібне ViewContext.RouteData.Values["controller"]для районів?

Відповіді:


217

З MVC2 можна використовувати ViewContext.RouteData.DataTokens["area"]


22
Якщо немає в області, ViewContext.RouteData.DataTokens ["область"] == null.
користувач202448

23
... і в MVC5 :)
Стефан

4
Лол .. жарт на тебе @Dante ... ну, чесно кажучи, його називають ASP.NET Core 1.0замість MVC6.. :-)
Росді Касім

FYI - з'ясував, що не так з моїм ajax POST не працюють ... будь ласка, перевірте, що у запитів ur ajax є область у URL-адресі ... вони все ще можуть знайти !!! подання, але вони не підтримують область ... якщо URL-адресі не вистачає області, коли запит зроблено.
Seabizkit

43
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]

3
Це найкращий, універсальний спосіб отримати інформацію про місцевість, якщо ви не перебуваєте в режимі перегляду чи контролера. Дякуємо, що опублікували це!
bdrelling

19

Ви можете отримати його від контролера, використовуючи:

ControllerContext.RouteData.DataTokens["area"]

@ user202338 Області були введені в MVC2, тому я б запідозрив це, але я не впевнений, чи змінили вони спосіб їх заселення колекцією DataTokens. Я бачу такі публікації: посилання, що говорять про його використання в MVC2.
Метт Пеннер

10

У ASP.NET Core 1.0 значення знайдено в

ViewContext.RouteData.Values ​​["область"];


Ти впевнений? Наскільки я пам'ятаю, він працював, коли ми запускали наш додаток на ASP.NET Core 2.0 і досі працює в ASP.NET Core 2.1 (перевірені хвилини тому).
zerox981

Ви маєте рацію, працюючи не лише для сторінок Razor (немає ViewContext - pageModel.RouteData.Values.TryGetValue("area", out object area)замість цього слід використовувати)
Роман Покровський

9

Я тільки що написав запис про журнал ab про це , ви можете відвідати його для отримання детальнішої інформації, але моя відповідь полягала в створенні методу розширення, показаного нижче.

Ключовим ключем було те, що ви витягуєте область MVC з .DataTokens та контролера / дії з .Values ​​RouteData.

public static MvcHtmlString TopMenuLink(this HtmlHelper htmlHelper, string linkText, string controller, string action, string area, string anchorTitle)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var url = urlHelper.Action(action, controller, new { @area = area });

        var anchor = new TagBuilder("a");
        anchor.InnerHtml = HttpUtility.HtmlEncode(linkText);
        anchor.MergeAttribute("href", url);
        anchor.Attributes.Add("title", anchorTitle);

        var listItem = new TagBuilder("li");
        listItem.InnerHtml = anchor.ToString(TagRenderMode.Normal);

        if (CheckForActiveItem(htmlHelper, controller, action, area))
            listItem.GenerateId("menu_active");

        return MvcHtmlString.Create(listItem.ToString(TagRenderMode.Normal));
    }

    private static bool CheckForActiveItem(HtmlHelper htmlHelper, string controller, string action, string area)
    {
        if (!CheckIfTokenMatches(htmlHelper, area, "area"))
            return false;

        if (!CheckIfValueMatches(htmlHelper, controller, "controller"))
            return false;

        return CheckIfValueMatches(htmlHelper, action, "action");
    }

    private static bool CheckIfValueMatches(HtmlHelper htmlHelper, string item, string dataToken)
    {
        var routeData = (string)htmlHelper.ViewContext.RouteData.Values[dataToken];

        if (routeData == null) return string.IsNullOrEmpty(item);

        return routeData == item;
    }

    private static bool CheckIfTokenMatches(HtmlHelper htmlHelper, string item, string dataToken)
    {
        var routeData = (string)htmlHelper.ViewContext.RouteData.DataTokens[dataToken];

        if (dataToken == "action" && item == "Index" && string.IsNullOrEmpty(routeData))
            return true;

        if (dataToken == "controller" && item == "Home" && string.IsNullOrEmpty(routeData))
            return true;

        if (routeData == null) return string.IsNullOrEmpty(item);

        return routeData == item;
    }

Тоді ви можете реалізувати його як нижче:

<ul id="menu">
@Html.TopMenuLink("Dashboard", "Home", "Index", "", "Click here for the dashboard.")
@Html.TopMenuLink("Courses", "Home", "Index", "Courses", "List of our Courses.")
</ul>

Чомусь я не можу знайти areaлексему в тому, що Valuesпотрібно, але мені потрібно було подивитися в DataTokens... поняття, чому.
Сиська

8

Я створив метод розширення для RouteDataцього повертає поточну назву області.

public static string GetAreaName(this RouteData routeData)
{
    object area;
    if (routeData.DataTokens.TryGetValue("area", out area))
    {
        return area as string;
    }

    return null;
}

Оскільки RouteDataвін доступний як на обох, так ControllerContextі до ViewContextнього можна отримати доступ у контролері та представленнях.

Тестування також дуже легко:

[TestFixture]
public class RouteDataExtensionsTests
{
    [Test]
    public void GetAreaName_should_return_area_name()
    {
        var routeData = new RouteData();
        routeData.DataTokens.Add("area", "Admin");
        routeData.GetAreaName().ShouldEqual("Admin");
    }

    [Test]
    public void GetAreaName_should_return_null_when_not_set()
    {
        var routeData = new RouteData();
        routeData.GetAreaName().ShouldBeNull();
    }
}

Не потрібно перевіряти, чи RouteData.DataTokensє нульовим, оскільки це завжди ініціалізується внутрішньо.


3

MVC Futures має метод AreaHelpers.GetAreaName (). Однак будьте обережні, якщо ви використовуєте цей метод. Використання поточної області для прийняття рішень виконання програми щодо вашої програми може призвести до важкої налагодження чи незахищеного коду.


1
Чи існує такий метод для контролерів? Я ненавиджу використання рядкових літералів у колекції.
Ерік Т

для використання контролером this.GetName()та для поточного використання методуMethodBase.GetCurrentMethod().Name
Nerdroid

3

Я знаю, що це старе, але також, коли у фільтрі, як ActionFilter, контекст не може легко надати вам інформацію про область.

Його можна знайти в наступному коді:

var routeData = filterContext.RequestContext.RouteData;

if (routeData.DataTokens["area"] != null)
    area = routeData.DataTokens["area"].ToString();

Таким чином, filterContext передається на заміщення, і правильний RouteData знаходиться під RequestContext. На базовому рівні є RoutData, але DataTokens НЕ має області в своєму словнику.


2

Щоб отримати ім'я області у поданні, в ASP.NET Core MVC 2.1:

@Context.GetRouteData().Values["area"]

2

Отримайте назву області у View (.NET Core 2.2):

ViewContext?.ActionDescriptor?.RouteValues["area"]

0

Я знаю, що це дуже давня публікація, але ми можемо використовувати властивість Значення точно так само, як і DataTokens

Url.RequestContext.RouteData.Values ​​["дія"] працював на мене.


0

Я не знаю чому, але прийнята відповідь не працює. Він повертає null з, наприклад (можливо, про mvc, я використовую .net core)

http: // localhost: 5000 / Admin / CustomerGroup

Я завжди налагоджую змінну і отримую дані з неї.

Спробуйте це. Це працює для мене

var area = ViewContext.RouteData.Values["area"]

Детальний логічний приклад

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.