답변:
MVC2부터는 ViewContext.RouteData.DataTokens["area"]
ASP.NET Core 1.0
대신에 불렀습니다 MVC6
.
ASP.NET Core 1.0에서이 값은
ViewContext.RouteData.Values [ "area"];
pageModel.RouteData.Values.TryGetValue("area", out object 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>
area
토큰을 찾을 수 없지만 ... Values
을보아야했습니다 DataTokens
. 왜 그런지 모르겠습니다.
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
항상 내부적으로 초기화되기 때문에 null 인지 확인할 필요가 없습니다 .
나는 이것이 오래되었다는 것을 알고 있지만 ActionFilter와 같은 필터에서 컨텍스트는 쉽게 지역 정보를 제공하지 않습니다.
다음 코드에서 찾을 수 있습니다.
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
따라서 재정의시 filterContext가 전달되고 RequestContext에서 올바른 RouteData가 발견됩니다. 기본 레벨에는 RoutData가 있지만 DataToken에는 사전에 영역이 없습니다.
나는 이것이 매우 오래된 게시물이라는 것을 알고 있지만 DataTokens와 정확히 같은 방식으로 Values 속성을 사용할 수 있습니다
Url.RequestContext.RouteData.Values [ "action"]이 저에게 효과적이었습니다.
왜 그런지 모르겠지만 허용 된 답변이 작동하지 않습니다. 예를 들어 null을 반환합니다 (아마도 mvc, .net core 사용)
나는 항상 변수를 디버깅하고 변수를 가져옵니다.
이 시도. 그것은 나를 위해 작동
var area = ViewContext.RouteData.Values["area"]
자세한 논리적 예
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";