Получить имя текущей области в представлении или контроллере - PullRequest
125 голосов
/ 27 апреля 2010

Как вы получаете текущее название области в представлении или контроллере?

Есть ли что-то вроде ViewContext.RouteData.Values["controller"] для областей?

Ответы [ 11 ]

212 голосов
/ 09 мая 2010

Начиная с MVC2 вы можете использовать ViewContext.RouteData.DataTokens["area"]

42 голосов
/ 11 апреля 2013
HttpContext.Current.Request.RequestContext.RouteData.DataTokens["area"]
19 голосов
/ 29 июля 2011

Вы можете получить его из контроллера, используя:

ControllerContext.RouteData.DataTokens["area"]
9 голосов
/ 01 декабря 2011

Я только что написал запись в журнале b об этом , вы можете посетить это для получения более подробной информации, но мой ответ заключался в создании метода расширения, показанного ниже.

Ключевым моментом было то, что вы извлекаете область MVC из .DataTokens, а контроллер / действие - из. Значения 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>
8 голосов
/ 22 ноября 2016

В ASP.NET Core 1.0 значение находится в

ViewContext.RouteData.Values ​​["area"];

8 голосов
/ 19 января 2013

Я создал метод расширения для 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 голосов
/ 28 декабря 2012

Я знаю, что это старый, но также, когда в фильтре, таком как ActionFilter, контекст не предоставляет вам информацию о области.

Его можно найти в следующем коде:

var routeData = filterContext.RequestContext.RouteData;

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

Таким образом, filterContext передается в переопределении, и правильные данные RouteData находятся в RequestContext. На базовом уровне есть RoutData, но токены данных НЕ имеют области в своем словаре.

3 голосов
/ 28 апреля 2010

MVC Futures имеет метод AreaHelpers.GetAreaName (). Однако будьте осторожны, если вы используете этот метод. Использование текущей области для принятия решений во время выполнения относительно вашего приложения может привести к сложному для отладки или небезопасному коду.

0 голосов
/ 06 марта 2019

Получить имя области в View (.NET Core 2.2):

ViewContext?.ActionDescriptor?.RouteValues["area"]
0 голосов
/ 18 января 2019

Чтобы получить имя области в представлении, в ASP.NET Core MVC 2.1:

@Context.GetRouteData().Values["area"]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...