ASP.NET MVC – 在视图或控制器中获取当前区域名称

如何在视图或控制器中获取当前区域名称?

有什么像ViewContext.RouteData.Values["controller"]的区域?

在MVC 2中,你可以使用ViewContext.RouteData.DataTokens["area"]

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

你可以从控制器使用:

 ControllerContext.RouteData.DataTokens["area"] 

我只是写了关于这个的日志条目 ,你可以访问它的更多细节,但我的答案是创build一个扩展方法,如下所示。

关键是你从.DataTokens中取出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创build了一个扩展方法,返回当前的区域名称。

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

由于RouteDataControllerContextViewContext上都可用,因此可以在您的控制器和视图中访问它。

testing也很容易:

 [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是否为空,因为它始终在内部初始化。

我知道这是旧的,而且,当在像ActionFilter的filter,上下文不容易提供您的区域信息。

它可以在以下代码中find:

 var routeData = filterContext.RequestContext.RouteData; if (routeData.DataTokens["area"] != null) area = routeData.DataTokens["area"].ToString(); 

所以filterContext被传递给override,并且在RequestContext下find正确的RouteData。 在基本级别有一个RoutData,但DataTokens在它的字典中没有区域。

在ASP.NET Core 1.0中可以find该值

ViewContext.RouteData.Values [ “区域”];

MVC期货有一个AreaHelpers.GetAreaName()方法。 但是,如果您使用此方法,请谨慎使用。 使用当前的区域来确定应用程序的运行时间可能会导致难以debugging或不安全的代码。

我知道这是一个非常非常老的post,但是我们可以像DataTokens一样使用Values属性

Url.RequestContext.RouteData.Values [“action”]为我工作。