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

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

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



답변

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


답변

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


답변

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

ControllerContext.RouteData.DataTokens["area"]


답변

ASP.NET Core 1.0에서이 값은

ViewContext.RouteData.Values ​​[ “area”];


답변

방금 이것에 대해 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>


답변

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 인지 확인할 필요가 없습니다 .


답변

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