보기 또는 컨트롤러에서 현재 영역 이름 가져 오기


126

뷰 또는 컨트롤러에서 현재 영역 이름을 어떻게 얻습니까?

ViewContext.RouteData.Values["controller"]지역 과 같은 것이 있습니까?

답변:


217

MVC2부터는 ViewContext.RouteData.DataTokens["area"]


22
영역에 없으면 ViewContext.RouteData.DataTokens [ "area"] == null입니다.
user202448

23
... 그리고 MVC5에서 :)
Stefan

4
Lol .. 농담이 @Dante에 있습니다 ... .. :-) ASP.NET Core 1.0대신에 불렀습니다 MVC6.
Rosdi Kasim

참고-내 아약스 POST에 문제가 있음을 알았습니다 ... 아 락스 요청에 URL 영역이 있는지 확인하십시오 ... 아직 찾을 수 있습니다! 보기가 가능하지만 요청시 URL에 영역이 없으면 영역을 유지하지 않습니다.
Seabizkit

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

3
뷰 또는 컨트롤러가 아닌 경우 지역 정보를 얻는 가장 보편적 인 방법입니다. 이것을 게시 해 주셔서 감사합니다!
bdrelling

19

다음을 사용하여 컨트롤러에서 가져올 수 있습니다.

ControllerContext.RouteData.DataTokens["area"]

@ user202338 영역이 MVC2에 도입되었으므로 의심 할 것 같지만 DataTokens 컬렉션을 채우는 방식이 변경되었는지 확실하지 않습니다. MVC2에서 사용하는 것에 대해 이야기하는 링크 와 같은 게시물이 있습니다.
매트 Penner

10

ASP.NET Core 1.0에서이 값은

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


확실합니까? 내가 기억할 수있는 한, 우리가 ASP.NET Core 2.0에서 앱을 실행할 때 효과가 있었고 지금도 ASP.NET Core 2.1 (현재 테스트 된)에서 여전히 작동하고 있습니다.
zerox981

당신은 Razor Pages를 위해서만 일하는 것이 맞지 않습니다 (ViewContext가 없습니다 – pageModel.RouteData.Values.TryGetValue("area", out object area)대신 사용되어야합니다)
Roman Pokrovskij

9

방금 이것에 대해 ab 로그 항목을 썼습니다. 자세한 내용을 보려면 해당 항목 을 방문하십시오. 그러나 내 대답은 아래에 표시된 확장 방법을 만드는 것이 었습니다.

핵심 요점은 .DataToken에서 MVC 영역을 가져오고 RouteData의 .Values에서 컨트롤러 / 액션을 가져 오는 것입니다.

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. 왜 그런지 모르겠습니다.
Syska

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모두 볼 수 있습니다 ControllerContextViewContext 그것은 당신의 컨트롤러와 뷰에 액세스 할 수 있습니다.

테스트하기도 매우 쉽습니다.

[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항상 내부적으로 초기화되기 때문에 null 인지 확인할 필요가 없습니다 .


3

MVC 선물 에는 AreaHelpers.GetAreaName () 메소드가 있습니다. 그러나이 방법을 사용하는 경우주의하십시오. 현재 영역을 사용하여 응용 프로그램에 대한 런타임 결정을 내리면 디버그하기 어렵거나 안전하지 않은 코드가 발생할 수 있습니다.


1
컨트롤러와 같은 방법이 있습니까? 나는 문자열 리터럴을 컬렉션으로 사용하는 것을 싫어합니다.
Erick T

컨트롤러 사용 this.GetName()및 현재 분석법 사용MethodBase.GetCurrentMethod().Name
Nerdroid

3

나는 이것이 오래되었다는 것을 알고 있지만 ActionFilter와 같은 필터에서 컨텍스트는 쉽게 지역 정보를 제공하지 않습니다.

다음 코드에서 찾을 수 있습니다.

var routeData = filterContext.RequestContext.RouteData;

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

따라서 재정의시 filterContext가 전달되고 RequestContext에서 올바른 RouteData가 발견됩니다. 기본 레벨에는 RoutData가 있지만 DataToken에는 사전에 영역이 없습니다.


2

보기에서 영역 이름을 가져 오려면 ASP.NET Core MVC 2.1에서 :

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

2

View에서 영역 이름을 가져옵니다 (.NET Core 2.2).

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

0

나는 이것이 매우 오래된 게시물이라는 것을 알고 있지만 DataTokens와 정확히 같은 방식으로 Values ​​속성을 사용할 수 있습니다

Url.RequestContext.RouteData.Values ​​[ "action"]이 저에게 효과적이었습니다.


0

왜 그런지 모르겠지만 허용 된 답변이 작동하지 않습니다. 예를 들어 null을 반환합니다 (아마도 mvc, .net core 사용)

http : // localhost : 5000 / Admin / CustomerGroup

나는 항상 변수를 디버깅하고 변수를 가져옵니다.

이 시도. 그것은 나를 위해 작동

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

자세한 논리적 예

Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.