如何在视图或控制器中获取当前区域名称?
有没有类似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日志条目,您可以访问它以获取更多详细信息,但我的答案是创建一个扩展方法,如下所示。
关键是您从 .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
返回当前区域名称。
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,因为它总是在内部初始化。
在 View (.NET Core 2.2) 中获取区域名称:
ViewContext?.ActionDescriptor?.RouteValues["area"]
MVC Futures有一个 AreaHelpers.GetAreaName() 方法。但是,如果您使用此方法,请务必小心。使用当前区域对应用程序做出运行时决策可能会导致难以调试或不安全的代码。
我知道这是旧的,但是,在像 ActionFilter 这样的过滤器中,上下文不会轻易地为您提供区域信息。
它可以在以下代码中找到:
var routeData = filterContext.RequestContext.RouteData;
if (routeData.DataTokens["area"] != null)
area = routeData.DataTokens["area"].ToString();
所以 filterContext 在覆盖上被传入,并且在 RequestContext 下找到了正确的 RouteData。Base 级别有一个 RoutData,但 DataTokens 的字典中没有该区域。
要在视图中获取区域名称,在 ASP.NET Core MVC 2.1 中:
@Context.GetRouteData().Values["area"]
我不知道为什么,但接受的答案不起作用。它使用 eg 返回 null (可能是关于 mvc,我使用 .net core )
我总是调试变量并从中获取数据。
尝试这个。这个对我有用
var area = ViewContext.RouteData.Values["area"]
详细的逻辑示例
Layout = ViewContext.RouteData.Values["area"] == null ? "_LayoutUser" : "_LayoutAdmin";
我知道这是一篇非常古老的帖子,但我们可以使用与 DataTokens 完全相同的方式使用 Values 属性
Url.RequestContext.RouteData.Values["action"] 为我工作。
ASP .Net 核心 3.1
场景:我想在 ViewCompnent Invoke 方法中检索当前区域名称。
public IViewComponentResult Invoke()
{
string areaName = this.RouteData.Values["area"];
//Your code here...
return View(items);
}